Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb, and openmp
release_90 branch r370514, and update version numbers.
This commit is contained in:
parent
22f75ae738
24632cab8a
c91bd9b242
0f40b62144
7a63c3fd2d
bc9477c1e1
cd5ff43da5
1756886afc
1ac1019db8
commit
6a82ac86f0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang900-import/; revision=351722
@ -402,7 +402,6 @@ static void AsanInitInternal() {
|
||||
asan_init_is_running = true;
|
||||
|
||||
CacheBinaryName();
|
||||
CheckASLR();
|
||||
|
||||
// Initialize flags. This must be done early, because most of the
|
||||
// initialization steps look at flags().
|
||||
@ -450,6 +449,7 @@ static void AsanInitInternal() {
|
||||
SetLowLevelAllocateCallback(OnLowLevelAllocate);
|
||||
|
||||
InitializeAsanInterceptors();
|
||||
CheckASLR();
|
||||
|
||||
// Enable system log ("adb logcat") on Android.
|
||||
// Doing this before interceptors are initialized crashes in:
|
||||
|
@ -403,7 +403,6 @@ void __msan_init() {
|
||||
AvoidCVE_2016_2143();
|
||||
|
||||
CacheBinaryName();
|
||||
CheckASLR();
|
||||
InitializeFlags();
|
||||
|
||||
// Install tool-specific callbacks in sanitizer_common.
|
||||
@ -412,6 +411,7 @@ void __msan_init() {
|
||||
__sanitizer_set_report_path(common_flags()->log_path);
|
||||
|
||||
InitializeInterceptors();
|
||||
CheckASLR();
|
||||
InitTlsSize();
|
||||
InstallDeadlySignalHandlers(MsanOnDeadlySignal);
|
||||
InstallAtExitHandler(); // Needs __cxa_atexit interceptor.
|
||||
|
@ -2011,6 +2011,35 @@ void CheckASLR() {
|
||||
CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
|
||||
ReExec();
|
||||
}
|
||||
#elif SANITIZER_FREEBSD
|
||||
int aslr_pie;
|
||||
uptr len = sizeof(aslr_pie);
|
||||
#if SANITIZER_WORDSIZE == 64
|
||||
if (UNLIKELY(internal_sysctlbyname("kern.elf64.aslr.pie_enable",
|
||||
&aslr_pie, &len, NULL, 0) == -1)) {
|
||||
// We're making things less 'dramatic' here since
|
||||
// the OID is not necessarily guaranteed to be here
|
||||
// just yet regarding FreeBSD release
|
||||
return;
|
||||
}
|
||||
|
||||
if (aslr_pie > 0) {
|
||||
Printf("This sanitizer is not compatible with enabled ASLR "
|
||||
"and binaries compiled with PIE\n");
|
||||
Die();
|
||||
}
|
||||
#endif
|
||||
// there might be 32 bits compat for 64 bits
|
||||
if (UNLIKELY(internal_sysctlbyname("kern.elf32.aslr.pie_enable",
|
||||
&aslr_pie, &len, NULL, 0) == -1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aslr_pie > 0) {
|
||||
Printf("This sanitizer is not compatible with enabled ASLR "
|
||||
"and binaries compiled with PIE\n");
|
||||
Die();
|
||||
}
|
||||
#else
|
||||
// Do nothing
|
||||
#endif
|
||||
|
@ -409,7 +409,7 @@ public:
|
||||
static const mask xdigit = _ISxdigit;
|
||||
static const mask blank = _ISblank;
|
||||
#if defined(__mips__)
|
||||
static const mask __regex_word = static_cast<char_class_type>(_ISbit(15));
|
||||
static const mask __regex_word = static_cast<mask>(_ISbit(15));
|
||||
#else
|
||||
static const mask __regex_word = 0x80;
|
||||
#endif
|
||||
|
@ -23,16 +23,11 @@
|
||||
# include <__external_threading>
|
||||
#elif !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
|
||||
typedef ::timespec __libcpp_timespec_t;
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
# include <pthread.h>
|
||||
# include <sched.h>
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
|
||||
defined(_LIBCPP_HAS_THREAD_API_WIN32)
|
||||
@ -47,8 +42,16 @@ _LIBCPP_PUSH_MACROS
|
||||
#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
|
||||
#endif
|
||||
|
||||
typedef ::timespec __libcpp_timespec_t;
|
||||
#endif // !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
// Mutex
|
||||
typedef pthread_mutex_t __libcpp_mutex_t;
|
||||
@ -76,7 +79,7 @@ typedef pthread_t __libcpp_thread_t;
|
||||
typedef pthread_key_t __libcpp_tls_key;
|
||||
|
||||
#define _LIBCPP_TLS_DESTRUCTOR_CC
|
||||
#else
|
||||
#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
|
||||
// Mutex
|
||||
typedef void* __libcpp_mutex_t;
|
||||
#define _LIBCPP_MUTEX_INITIALIZER 0
|
||||
@ -109,8 +112,9 @@ typedef void* __libcpp_thread_t;
|
||||
typedef long __libcpp_tls_key;
|
||||
|
||||
#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
|
||||
|
||||
#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
|
||||
// Mutex
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
|
||||
@ -205,6 +209,8 @@ void *__libcpp_tls_get(__libcpp_tls_key __key);
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
|
||||
|
||||
#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
|
||||
defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
@ -475,10 +481,10 @@ get_id() _NOEXCEPT
|
||||
|
||||
} // this_thread
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_THREADS
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_THREADS
|
||||
|
||||
#endif // _LIBCPP_THREADING_SUPPORT
|
||||
|
@ -31,6 +31,7 @@
|
||||
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
||||
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/User.h"
|
||||
@ -263,12 +264,14 @@ Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
|
||||
/// This first performs a normal RAUW of I with SimpleV. It then recursively
|
||||
/// attempts to simplify those users updated by the operation. The 'I'
|
||||
/// instruction must not be equal to the simplified value 'SimpleV'.
|
||||
/// If UnsimplifiedUsers is provided, instructions that could not be simplified
|
||||
/// are added to it.
|
||||
///
|
||||
/// The function returns true if any simplifications were performed.
|
||||
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr);
|
||||
bool replaceAndRecursivelySimplify(
|
||||
Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr,
|
||||
SmallSetVector<Instruction *, 8> *UnsimplifiedUsers = nullptr);
|
||||
|
||||
/// Recursively attempt to simplify an instruction.
|
||||
///
|
||||
|
@ -244,6 +244,7 @@ class InlineAsm final : public Value {
|
||||
Constraint_m,
|
||||
Constraint_o,
|
||||
Constraint_v,
|
||||
Constraint_A,
|
||||
Constraint_Q,
|
||||
Constraint_R,
|
||||
Constraint_S,
|
||||
|
@ -5221,14 +5221,16 @@ Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &SQ,
|
||||
/// If we have a pre-simplified value in 'SimpleV', that is forcibly used to
|
||||
/// replace the instruction 'I'. Otherwise, we simply add 'I' to the list of
|
||||
/// instructions to process and attempt to simplify it using
|
||||
/// InstructionSimplify.
|
||||
/// InstructionSimplify. Recursively visited users which could not be
|
||||
/// simplified themselves are to the optional UnsimplifiedUsers set for
|
||||
/// further processing by the caller.
|
||||
///
|
||||
/// This routine returns 'true' only when *it* simplifies something. The passed
|
||||
/// in simplified value does not count toward this.
|
||||
static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
static bool replaceAndRecursivelySimplifyImpl(
|
||||
Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
SmallSetVector<Instruction *, 8> *UnsimplifiedUsers = nullptr) {
|
||||
bool Simplified = false;
|
||||
SmallSetVector<Instruction *, 8> Worklist;
|
||||
const DataLayout &DL = I->getModule()->getDataLayout();
|
||||
@ -5258,8 +5260,11 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
|
||||
|
||||
// See if this instruction simplifies.
|
||||
SimpleV = SimplifyInstruction(I, {DL, TLI, DT, AC});
|
||||
if (!SimpleV)
|
||||
if (!SimpleV) {
|
||||
if (UnsimplifiedUsers)
|
||||
UnsimplifiedUsers->insert(I);
|
||||
continue;
|
||||
}
|
||||
|
||||
Simplified = true;
|
||||
|
||||
@ -5285,16 +5290,17 @@ bool llvm::recursivelySimplifyInstruction(Instruction *I,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
return replaceAndRecursivelySimplifyImpl(I, nullptr, TLI, DT, AC);
|
||||
return replaceAndRecursivelySimplifyImpl(I, nullptr, TLI, DT, AC, nullptr);
|
||||
}
|
||||
|
||||
bool llvm::replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
bool llvm::replaceAndRecursivelySimplify(
|
||||
Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
SmallSetVector<Instruction *, 8> *UnsimplifiedUsers) {
|
||||
assert(I != SimpleV && "replaceAndRecursivelySimplify(X,X) is not valid!");
|
||||
assert(SimpleV && "Must provide a simplified value.");
|
||||
return replaceAndRecursivelySimplifyImpl(I, SimpleV, TLI, DT, AC);
|
||||
return replaceAndRecursivelySimplifyImpl(I, SimpleV, TLI, DT, AC,
|
||||
UnsimplifiedUsers);
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
@ -140,7 +140,16 @@ unsigned LLVMGetLastEnumAttributeKind(void) {
|
||||
|
||||
LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID,
|
||||
uint64_t Val) {
|
||||
return wrap(Attribute::get(*unwrap(C), (Attribute::AttrKind)KindID, Val));
|
||||
auto &Ctx = *unwrap(C);
|
||||
auto AttrKind = (Attribute::AttrKind)KindID;
|
||||
|
||||
if (AttrKind == Attribute::AttrKind::ByVal) {
|
||||
// After r362128, byval attributes need to have a type attribute. Provide a
|
||||
// NULL one until a proper API is added for this.
|
||||
return wrap(Attribute::getWithByValType(Ctx, NULL));
|
||||
} else {
|
||||
return wrap(Attribute::get(Ctx, AttrKind, Val));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A) {
|
||||
|
@ -10579,7 +10579,7 @@ static SDValue performPostLD1Combine(SDNode *N,
|
||||
// are predecessors to each other or the Vector.
|
||||
SmallPtrSet<const SDNode *, 32> Visited;
|
||||
SmallVector<const SDNode *, 16> Worklist;
|
||||
Visited.insert(N);
|
||||
Visited.insert(Addr.getNode());
|
||||
Worklist.push_back(User);
|
||||
Worklist.push_back(LD);
|
||||
Worklist.push_back(Vector.getNode());
|
||||
@ -11995,6 +11995,14 @@ bool AArch64TargetLowering::isMaskAndCmp0FoldingBeneficial(
|
||||
return Mask->getValue().isPowerOf2();
|
||||
}
|
||||
|
||||
bool AArch64TargetLowering::shouldExpandShift(SelectionDAG &DAG,
|
||||
SDNode *N) const {
|
||||
if (DAG.getMachineFunction().getFunction().hasMinSize() &&
|
||||
!Subtarget->isTargetWindows())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AArch64TargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const {
|
||||
// Update IsSplitCSR in AArch64unctionInfo.
|
||||
AArch64FunctionInfo *AFI = Entry->getParent()->getInfo<AArch64FunctionInfo>();
|
||||
|
@ -480,11 +480,7 @@ class AArch64TargetLowering : public TargetLowering {
|
||||
return VT.getSizeInBits() >= 64; // vector 'bic'
|
||||
}
|
||||
|
||||
bool shouldExpandShift(SelectionDAG &DAG, SDNode *N) const override {
|
||||
if (DAG.getMachineFunction().getFunction().hasMinSize())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool shouldExpandShift(SelectionDAG &DAG, SDNode *N) const override;
|
||||
|
||||
bool shouldTransformSignedTruncationCheck(EVT XVT,
|
||||
unsigned KeptBits) const override {
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
@ -1928,6 +1929,17 @@ bool AArch64InstrInfo::isCandidateToMergeOrPair(const MachineInstr &MI) const {
|
||||
if (isLdStPairSuppressed(MI))
|
||||
return false;
|
||||
|
||||
// Do not pair any callee-save store/reload instructions in the
|
||||
// prologue/epilogue if the CFI information encoded the operations as separate
|
||||
// instructions, as that will cause the size of the actual prologue to mismatch
|
||||
// with the prologue size recorded in the Windows CFI.
|
||||
const MCAsmInfo *MAI = MI.getMF()->getTarget().getMCAsmInfo();
|
||||
bool NeedsWinCFI = MAI->usesWindowsCFI() &&
|
||||
MI.getMF()->getFunction().needsUnwindTableEntry();
|
||||
if (NeedsWinCFI && (MI.getFlag(MachineInstr::FrameSetup) ||
|
||||
MI.getFlag(MachineInstr::FrameDestroy)))
|
||||
return false;
|
||||
|
||||
// On some CPUs quad load/store pairs are slower than two single load/stores.
|
||||
if (Subtarget.isPaired128Slow()) {
|
||||
switch (MI.getOpcode()) {
|
||||
|
@ -3625,8 +3625,25 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
|
||||
BaseReg, IDLoc, STI);
|
||||
TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(OffsetOp.isExpr() && "expected expression operand kind");
|
||||
if (inPicMode()) {
|
||||
// FIXME:
|
||||
// a) Fix lw/sw $reg, symbol($reg) instruction expanding.
|
||||
// b) If expression includes offset (sym + number), do not
|
||||
// encode the offset into a relocation. Take it in account
|
||||
// in the last load/store instruction.
|
||||
// c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
|
||||
// do not exceed 16-bit.
|
||||
// d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
|
||||
// of R_MIPS_GOT_DISP in appropriate cases to reduce number
|
||||
// of GOT entries.
|
||||
expandLoadAddress(TmpReg, Mips::NoRegister, OffsetOp, !ABI.ArePtrs64bit(),
|
||||
IDLoc, Out, STI);
|
||||
TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, 0, IDLoc, STI);
|
||||
} else {
|
||||
assert(OffsetOp.isExpr() && "expected expression operand kind");
|
||||
const MCExpr *ExprOffset = OffsetOp.getExpr();
|
||||
MCOperand LoOperand = MCOperand::createExpr(
|
||||
MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
|
||||
|
@ -179,6 +179,9 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
|
||||
// operand and need no special handling.
|
||||
OutOps.push_back(Op);
|
||||
return false;
|
||||
case InlineAsm::Constraint_A:
|
||||
OutOps.push_back(Op);
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2413,6 +2413,8 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
|
||||
case 'J':
|
||||
case 'K':
|
||||
return C_Immediate;
|
||||
case 'A':
|
||||
return C_Memory;
|
||||
}
|
||||
}
|
||||
return TargetLowering::getConstraintType(Constraint);
|
||||
@ -2442,6 +2444,21 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
|
||||
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
|
||||
}
|
||||
|
||||
unsigned
|
||||
RISCVTargetLowering::getInlineAsmMemConstraint(StringRef ConstraintCode) const {
|
||||
// Currently only support length 1 constraints.
|
||||
if (ConstraintCode.size() == 1) {
|
||||
switch (ConstraintCode[0]) {
|
||||
case 'A':
|
||||
return InlineAsm::Constraint_A;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
|
||||
}
|
||||
|
||||
void RISCVTargetLowering::LowerAsmOperandForConstraint(
|
||||
SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops,
|
||||
SelectionDAG &DAG) const {
|
||||
|
@ -93,6 +93,9 @@ class RISCVTargetLowering : public TargetLowering {
|
||||
const char *getTargetNodeName(unsigned Opcode) const override;
|
||||
|
||||
ConstraintType getConstraintType(StringRef Constraint) const override;
|
||||
|
||||
unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
|
||||
|
||||
std::pair<unsigned, const TargetRegisterClass *>
|
||||
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
|
||||
StringRef Constraint, MVT VT) const override;
|
||||
|
@ -140,8 +140,8 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
|
||||
// don't assume the variables to be DSO local unless we actually know
|
||||
// that for sure. This only has to be done for variables; for functions
|
||||
// the linker can insert thunks for calling functions from another DLL.
|
||||
if (TT.isWindowsGNUEnvironment() && GV && GV->isDeclarationForLinker() &&
|
||||
isa<GlobalVariable>(GV))
|
||||
if (TT.isWindowsGNUEnvironment() && TT.isOSBinFormatCOFF() && GV &&
|
||||
GV->isDeclarationForLinker() && isa<GlobalVariable>(GV))
|
||||
return false;
|
||||
|
||||
// On COFF, don't mark 'extern_weak' symbols as DSO local. If these symbols
|
||||
@ -154,7 +154,9 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
|
||||
// Make an exception for windows OS in the triple: Some firmware builds use
|
||||
// *-win32-macho triples. This (accidentally?) produced windows relocations
|
||||
// without GOT tables in older clang versions; Keep this behaviour.
|
||||
if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO()))
|
||||
// Some JIT users use *-win32-elf triples; these shouldn't use GOT tables
|
||||
// either.
|
||||
if (TT.isOSBinFormatCOFF() || TT.isOSWindows())
|
||||
return true;
|
||||
|
||||
// Most PIC code sequences that assume that a symbol is local cannot
|
||||
|
@ -5059,6 +5059,14 @@ bool X86TargetLowering::shouldFoldMaskToVariableShiftPair(SDValue Y) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool X86TargetLowering::shouldExpandShift(SelectionDAG &DAG,
|
||||
SDNode *N) const {
|
||||
if (DAG.getMachineFunction().getFunction().hasMinSize() &&
|
||||
!Subtarget.isOSWindows())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool X86TargetLowering::shouldSplatInsEltVarIndex(EVT VT) const {
|
||||
// Any legal vector type can be splatted more efficiently than
|
||||
// loading/spilling from memory.
|
||||
@ -44096,7 +44104,8 @@ static SDValue combineScalarToVector(SDNode *N, SelectionDAG &DAG) {
|
||||
|
||||
// Simplify PMULDQ and PMULUDQ operations.
|
||||
static SDValue combinePMULDQ(SDNode *N, SelectionDAG &DAG,
|
||||
TargetLowering::DAGCombinerInfo &DCI) {
|
||||
TargetLowering::DAGCombinerInfo &DCI,
|
||||
const X86Subtarget &Subtarget) {
|
||||
SDValue LHS = N->getOperand(0);
|
||||
SDValue RHS = N->getOperand(1);
|
||||
|
||||
@ -44106,8 +44115,9 @@ static SDValue combinePMULDQ(SDNode *N, SelectionDAG &DAG,
|
||||
return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), RHS, LHS);
|
||||
|
||||
// Multiply by zero.
|
||||
// Don't return RHS as it may contain UNDEFs.
|
||||
if (ISD::isBuildVectorAllZeros(RHS.getNode()))
|
||||
return RHS;
|
||||
return getZeroVector(N->getSimpleValueType(0), Subtarget, DAG, SDLoc(N));
|
||||
|
||||
// Aggressively peek through ops to get at the demanded low bits.
|
||||
APInt DemandedMask = APInt::getLowBitsSet(64, 32);
|
||||
@ -44315,7 +44325,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
|
||||
case X86ISD::PCMPEQ:
|
||||
case X86ISD::PCMPGT: return combineVectorCompare(N, DAG, Subtarget);
|
||||
case X86ISD::PMULDQ:
|
||||
case X86ISD::PMULUDQ: return combinePMULDQ(N, DAG, DCI);
|
||||
case X86ISD::PMULUDQ: return combinePMULDQ(N, DAG, DCI, Subtarget);
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
|
@ -863,11 +863,7 @@ namespace llvm {
|
||||
return VTIsOk(XVT) && VTIsOk(KeptBitsVT);
|
||||
}
|
||||
|
||||
bool shouldExpandShift(SelectionDAG &DAG, SDNode *N) const override {
|
||||
if (DAG.getMachineFunction().getFunction().hasMinSize())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool shouldExpandShift(SelectionDAG &DAG, SDNode *N) const override;
|
||||
|
||||
bool shouldSplatInsEltVarIndex(EVT VT) const override;
|
||||
|
||||
|
@ -146,6 +146,9 @@ unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
|
||||
return X86II::MO_DLLIMPORT;
|
||||
return X86II::MO_COFFSTUB;
|
||||
}
|
||||
// Some JIT users use *-win32-elf triples; these shouldn't use GOT tables.
|
||||
if (isOSWindows())
|
||||
return X86II::MO_NO_FLAG;
|
||||
|
||||
if (is64Bit()) {
|
||||
// ELF supports a large, truly PIC code model with non-PC relative GOT
|
||||
|
@ -711,7 +711,7 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
|
||||
|
||||
auto setDest = [LoopExit, ContinueOnTrue](BasicBlock *Src, BasicBlock *Dest,
|
||||
ArrayRef<BasicBlock *> NextBlocks,
|
||||
BasicBlock *CurrentHeader,
|
||||
BasicBlock *BlockInLoop,
|
||||
bool NeedConditional) {
|
||||
auto *Term = cast<BranchInst>(Src->getTerminator());
|
||||
if (NeedConditional) {
|
||||
@ -723,7 +723,9 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
|
||||
if (Dest != LoopExit) {
|
||||
BasicBlock *BB = Src;
|
||||
for (BasicBlock *Succ : successors(BB)) {
|
||||
if (Succ == CurrentHeader)
|
||||
// Preserve the incoming value from BB if we are jumping to the block
|
||||
// in the current loop.
|
||||
if (Succ == BlockInLoop)
|
||||
continue;
|
||||
for (PHINode &Phi : Succ->phis())
|
||||
Phi.removeIncomingValue(BB, false);
|
||||
@ -794,7 +796,7 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
|
||||
// unconditional branch for some iterations.
|
||||
NeedConditional = false;
|
||||
|
||||
setDest(Headers[i], Dest, Headers, Headers[i], NeedConditional);
|
||||
setDest(Headers[i], Dest, Headers, HeaderSucc[i], NeedConditional);
|
||||
}
|
||||
|
||||
// Set up latches to branch to the new header in the unrolled iterations or
|
||||
|
@ -165,7 +165,7 @@ LANGSTANDARD(opencl12, "cl1.2",
|
||||
LANGSTANDARD(opencl20, "cl2.0",
|
||||
OpenCL, "OpenCL 2.0",
|
||||
LineComment | C99 | Digraphs | HexFloat | OpenCL)
|
||||
LANGSTANDARD(openclcpp, "c++",
|
||||
LANGSTANDARD(openclcpp, "clc++",
|
||||
OpenCL, "C++ for OpenCL",
|
||||
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
|
||||
Digraphs | HexFloat | OpenCL)
|
||||
|
@ -60,6 +60,10 @@ bool RISCVTargetInfo::validateAsmConstraint(
|
||||
// A floating-point register.
|
||||
Info.setAllowsRegister();
|
||||
return true;
|
||||
case 'A':
|
||||
// An address that is held in a general-purpose register.
|
||||
Info.setAllowsMemory();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,13 @@ class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setMaxAtomicWidth() override {
|
||||
MaxAtomicPromoteWidth = 128;
|
||||
|
||||
if (HasA)
|
||||
MaxAtomicInlineWidth = 32;
|
||||
}
|
||||
};
|
||||
class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
|
||||
public:
|
||||
@ -110,6 +117,13 @@ class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setMaxAtomicWidth() override {
|
||||
MaxAtomicPromoteWidth = 128;
|
||||
|
||||
if (HasA)
|
||||
MaxAtomicInlineWidth = 64;
|
||||
}
|
||||
};
|
||||
} // namespace targets
|
||||
} // namespace clang
|
||||
|
@ -15350,7 +15350,7 @@ ndrange_t __ovld ndrange_3D(const size_t[3]);
|
||||
ndrange_t __ovld ndrange_3D(const size_t[3], const size_t[3]);
|
||||
ndrange_t __ovld ndrange_3D(const size_t[3], const size_t[3], const size_t[3]);
|
||||
|
||||
int __ovld enqueue_marker(queue_t, uint, const __private clk_event_t*, __private clk_event_t*);
|
||||
int __ovld enqueue_marker(queue_t, uint, const clk_event_t*, clk_event_t*);
|
||||
|
||||
void __ovld retain_event(clk_event_t);
|
||||
|
||||
|
@ -1225,7 +1225,8 @@ static bool checkTupleLikeDecomposition(Sema &S,
|
||||
if (E.isInvalid())
|
||||
return true;
|
||||
RefVD->setInit(E.get());
|
||||
RefVD->checkInitIsICE();
|
||||
if (!E.get()->isValueDependent())
|
||||
RefVD->checkInitIsICE();
|
||||
|
||||
E = S.BuildDeclarationNameExpr(CXXScopeSpec(),
|
||||
DeclarationNameInfo(B->getDeclName(), Loc),
|
||||
|
@ -4692,6 +4692,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
|
||||
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
|
||||
TemplateArgLists.addOuterTemplateArguments(None);
|
||||
|
||||
Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext());
|
||||
EnterExpressionEvaluationContext ConstantEvaluated(
|
||||
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
|
||||
return SemaRef.SubstExpr(Param->getDefaultArgument(), TemplateArgLists);
|
||||
|
@ -7390,8 +7390,22 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
|
||||
bool IsPointee =
|
||||
ChunkIndex > 0 &&
|
||||
(D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Pointer ||
|
||||
D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::BlockPointer ||
|
||||
D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Reference);
|
||||
D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Reference ||
|
||||
D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::BlockPointer);
|
||||
// For pointers/references to arrays the next chunk is always an array
|
||||
// followed by any number of parentheses.
|
||||
if (!IsPointee && ChunkIndex > 1) {
|
||||
auto AdjustedCI = ChunkIndex - 1;
|
||||
if (D.getTypeObject(AdjustedCI).Kind == DeclaratorChunk::Array)
|
||||
AdjustedCI--;
|
||||
// Skip over all parentheses.
|
||||
while (AdjustedCI > 0 &&
|
||||
D.getTypeObject(AdjustedCI).Kind == DeclaratorChunk::Paren)
|
||||
AdjustedCI--;
|
||||
if (D.getTypeObject(AdjustedCI).Kind == DeclaratorChunk::Pointer ||
|
||||
D.getTypeObject(AdjustedCI).Kind == DeclaratorChunk::Reference)
|
||||
IsPointee = true;
|
||||
}
|
||||
bool IsFuncReturnType =
|
||||
ChunkIndex > 0 &&
|
||||
D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Function;
|
||||
|
@ -56,7 +56,6 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
include(HandleLLVMOptions)
|
||||
|
||||
if(LLVM_INCLUDE_TESTS)
|
||||
set(Python_ADDITIONAL_VERSIONS 2.7)
|
||||
include(FindPythonInterp)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
message(FATAL_ERROR
|
||||
|
@ -189,6 +189,7 @@ struct Configuration {
|
||||
// Used for /thinlto-object-suffix-replace:
|
||||
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
|
||||
|
||||
uint64_t align = 4096;
|
||||
uint64_t imageBase = -1;
|
||||
uint64_t fileAlign = 512;
|
||||
uint64_t stackReserve = 1024 * 1024;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "llvm/Option/Option.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/Support/TarWriter.h"
|
||||
@ -270,13 +271,12 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
|
||||
}
|
||||
|
||||
void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
|
||||
StringRef symName,
|
||||
const Archive::Symbol &sym,
|
||||
StringRef parentName) {
|
||||
|
||||
auto reportBufferError = [=](Error &&e,
|
||||
StringRef childName) {
|
||||
auto reportBufferError = [=](Error &&e, StringRef childName) {
|
||||
fatal("could not get the buffer for the member defining symbol " +
|
||||
symName + ": " + parentName + "(" + childName + "): " +
|
||||
toCOFFString(sym) + ": " + parentName + "(" + childName + "): " +
|
||||
toString(std::move(e)));
|
||||
};
|
||||
|
||||
@ -287,7 +287,8 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
|
||||
reportBufferError(mbOrErr.takeError(), check(c.getFullName()));
|
||||
MemoryBufferRef mb = mbOrErr.get();
|
||||
enqueueTask([=]() {
|
||||
driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive);
|
||||
driver->addArchiveBuffer(mb, toCOFFString(sym), parentName,
|
||||
offsetInArchive);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -295,15 +296,16 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
|
||||
std::string childName = CHECK(
|
||||
c.getFullName(),
|
||||
"could not get the filename for the member defining symbol " +
|
||||
symName);
|
||||
toCOFFString(sym));
|
||||
auto future = std::make_shared<std::future<MBErrPair>>(
|
||||
createFutureForFile(childName));
|
||||
enqueueTask([=]() {
|
||||
auto mbOrErr = future->get();
|
||||
if (mbOrErr.second)
|
||||
reportBufferError(errorCodeToError(mbOrErr.second), childName);
|
||||
driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName,
|
||||
parentName, /* OffsetInArchive */ 0);
|
||||
driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
|
||||
toCOFFString(sym), parentName,
|
||||
/*OffsetInArchive=*/0);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1053,6 +1055,12 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
|
||||
});
|
||||
}
|
||||
|
||||
static const char *libcallRoutineNames[] = {
|
||||
#define HANDLE_LIBCALL(code, name) name,
|
||||
#include "llvm/IR/RuntimeLibcalls.def"
|
||||
#undef HANDLE_LIBCALL
|
||||
};
|
||||
|
||||
void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
||||
// Needed for LTO.
|
||||
InitializeAllTargetInfos();
|
||||
@ -1421,6 +1429,13 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
||||
for (auto *arg : args.filtered(OPT_section))
|
||||
parseSection(arg->getValue());
|
||||
|
||||
// Handle /align
|
||||
if (auto *arg = args.getLastArg(OPT_align)) {
|
||||
parseNumbers(arg->getValue(), &config->align);
|
||||
if (!isPowerOf2_64(config->align))
|
||||
error("/align: not a power of two: " + StringRef(arg->getValue()));
|
||||
}
|
||||
|
||||
// Handle /aligncomm
|
||||
for (auto *arg : args.filtered(OPT_aligncomm))
|
||||
parseAligncomm(arg->getValue());
|
||||
@ -1748,6 +1763,15 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
||||
u->weakAlias = symtab->addUndefined(to);
|
||||
}
|
||||
|
||||
// If any inputs are bitcode files, the LTO code generator may create
|
||||
// references to library functions that are not explicit in the bitcode
|
||||
// file's symbol table. If any of those library functions are defined in a
|
||||
// bitcode file in an archive member, we need to arrange to use LTO to
|
||||
// compile those archive members by adding them to the link beforehand.
|
||||
if (!BitcodeFile::instances.empty())
|
||||
for (const char *s : libcallRoutineNames)
|
||||
symtab->addLibcall(s);
|
||||
|
||||
// Windows specific -- if __load_config_used can be resolved, resolve it.
|
||||
if (symtab->findUnderscore("_load_config_used"))
|
||||
addUndefined(mangle("_load_config_used"));
|
||||
|
@ -72,7 +72,7 @@ class LinkerDriver {
|
||||
void parseDirectives(InputFile *file);
|
||||
|
||||
// Used by ArchiveFile to enqueue members.
|
||||
void enqueueArchiveMember(const Archive::Child &c, StringRef symName,
|
||||
void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym,
|
||||
StringRef parentName);
|
||||
|
||||
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);
|
||||
|
@ -85,16 +85,16 @@ void ArchiveFile::parse() {
|
||||
}
|
||||
|
||||
// Returns a buffer pointing to a member file containing a given symbol.
|
||||
void ArchiveFile::addMember(const Archive::Symbol *sym) {
|
||||
void ArchiveFile::addMember(const Archive::Symbol &sym) {
|
||||
const Archive::Child &c =
|
||||
CHECK(sym->getMember(),
|
||||
"could not get the member for symbol " + sym->getName());
|
||||
CHECK(sym.getMember(),
|
||||
"could not get the member for symbol " + toCOFFString(sym));
|
||||
|
||||
// Return an empty buffer if we have already returned the same buffer.
|
||||
if (!seen.insert(c.getChildOffset()).second)
|
||||
return;
|
||||
|
||||
driver->enqueueArchiveMember(c, sym->getName(), getName());
|
||||
driver->enqueueArchiveMember(c, sym, getName());
|
||||
}
|
||||
|
||||
std::vector<MemoryBufferRef> getArchiveMembers(Archive *file) {
|
||||
|
@ -96,7 +96,7 @@ class ArchiveFile : public InputFile {
|
||||
// Enqueues an archive member load for the given symbol. If we've already
|
||||
// enqueued a load for the same archive member, this function does nothing,
|
||||
// which ensures that we don't load the same member more than once.
|
||||
void addMember(const Archive::Symbol *sym);
|
||||
void addMember(const Archive::Symbol &sym);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Archive> file;
|
||||
|
@ -179,7 +179,7 @@ void SymbolTable::loadMinGWAutomaticImports() {
|
||||
log("Loading lazy " + l->getName() + " from " + l->file->getName() +
|
||||
" for automatic import");
|
||||
l->pendingArchiveLoad = true;
|
||||
l->file->addMember(&l->sym);
|
||||
l->file->addMember(l->sym);
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,13 +363,13 @@ Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f,
|
||||
if (auto *l = dyn_cast<Lazy>(s)) {
|
||||
if (!s->pendingArchiveLoad) {
|
||||
s->pendingArchiveLoad = true;
|
||||
l->file->addMember(&l->sym);
|
||||
l->file->addMember(l->sym);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) {
|
||||
void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol &sym) {
|
||||
StringRef name = sym.getName();
|
||||
Symbol *s;
|
||||
bool wasInserted;
|
||||
@ -382,7 +382,7 @@ void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) {
|
||||
if (!u || u->weakAlias || s->pendingArchiveLoad)
|
||||
return;
|
||||
s->pendingArchiveLoad = true;
|
||||
f->addMember(&sym);
|
||||
f->addMember(sym);
|
||||
}
|
||||
|
||||
void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) {
|
||||
@ -505,6 +505,18 @@ Symbol *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SymbolTable::addLibcall(StringRef name) {
|
||||
Symbol *sym = findUnderscore(name);
|
||||
if (!sym)
|
||||
return;
|
||||
|
||||
if (Lazy *l = dyn_cast<Lazy>(sym)) {
|
||||
MemoryBufferRef mb = l->getMemberBuffer();
|
||||
if (identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode)
|
||||
addUndefined(sym->getName());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Chunk *> SymbolTable::getChunks() {
|
||||
std::vector<Chunk *> res;
|
||||
for (ObjFile *file : ObjFile::instances) {
|
||||
|
@ -83,7 +83,7 @@ class SymbolTable {
|
||||
Symbol *addAbsolute(StringRef n, uint64_t va);
|
||||
|
||||
Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias);
|
||||
void addLazy(ArchiveFile *f, const Archive::Symbol sym);
|
||||
void addLazy(ArchiveFile *f, const Archive::Symbol &sym);
|
||||
Symbol *addAbsolute(StringRef n, COFFSymbolRef s);
|
||||
Symbol *addRegular(InputFile *f, StringRef n,
|
||||
const llvm::object::coff_symbol_generic *s = nullptr,
|
||||
@ -97,6 +97,7 @@ class SymbolTable {
|
||||
Symbol *addImportData(StringRef n, ImportFile *f);
|
||||
Symbol *addImportThunk(StringRef name, DefinedImportData *s,
|
||||
uint16_t machine);
|
||||
void addLibcall(StringRef name);
|
||||
|
||||
void reportDuplicate(Symbol *existing, InputFile *newFile);
|
||||
|
||||
|
@ -20,18 +20,23 @@ using namespace llvm::object;
|
||||
|
||||
using namespace lld::coff;
|
||||
|
||||
namespace lld {
|
||||
|
||||
static_assert(sizeof(SymbolUnion) <= 48,
|
||||
"symbols should be optimized for memory usage");
|
||||
|
||||
// Returns a symbol name for an error message.
|
||||
std::string lld::toString(coff::Symbol &b) {
|
||||
static std::string demangle(StringRef symName) {
|
||||
if (config->demangle)
|
||||
if (Optional<std::string> s = lld::demangleMSVC(b.getName()))
|
||||
if (Optional<std::string> s = demangleMSVC(symName))
|
||||
return *s;
|
||||
return b.getName();
|
||||
return symName;
|
||||
}
|
||||
std::string toString(coff::Symbol &b) { return demangle(b.getName()); }
|
||||
std::string toCOFFString(const Archive::Symbol &b) {
|
||||
return demangle(b.getName());
|
||||
}
|
||||
|
||||
namespace lld {
|
||||
namespace coff {
|
||||
|
||||
StringRef Symbol::getName() {
|
||||
@ -113,5 +118,14 @@ Defined *Undefined::getWeakAlias() {
|
||||
return d;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MemoryBufferRef Lazy::getMemberBuffer() {
|
||||
Archive::Child c =
|
||||
CHECK(sym.getMember(),
|
||||
"could not get the member for symbol " + toCOFFString(sym));
|
||||
return CHECK(c.getMemoryBufferRef(),
|
||||
"could not get the buffer for the member defining symbol " +
|
||||
toCOFFString(sym));
|
||||
}
|
||||
} // namespace coff
|
||||
} // namespace lld
|
||||
|
@ -21,6 +21,14 @@
|
||||
#include <vector>
|
||||
|
||||
namespace lld {
|
||||
|
||||
std::string toString(coff::Symbol &b);
|
||||
|
||||
// There are two different ways to convert an Archive::Symbol to a string:
|
||||
// One for Microsoft name mangling and one for Itanium name mangling.
|
||||
// Call the functions toCOFFString and toELFString, not just toString.
|
||||
std::string toCOFFString(const coff::Archive::Symbol &b);
|
||||
|
||||
namespace coff {
|
||||
|
||||
using llvm::object::Archive;
|
||||
@ -257,6 +265,8 @@ class Lazy : public Symbol {
|
||||
|
||||
static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
|
||||
|
||||
MemoryBufferRef getMemberBuffer();
|
||||
|
||||
ArchiveFile *file;
|
||||
|
||||
private:
|
||||
@ -429,7 +439,6 @@ void replaceSymbol(Symbol *s, ArgT &&... arg) {
|
||||
}
|
||||
} // namespace coff
|
||||
|
||||
std::string toString(coff::Symbol &b);
|
||||
} // namespace lld
|
||||
|
||||
#endif
|
||||
|
@ -626,6 +626,9 @@ void Writer::run() {
|
||||
|
||||
writeMapFile(outputSections);
|
||||
|
||||
if (errorCount())
|
||||
return;
|
||||
|
||||
ScopedTimer t2(diskCommitTimer);
|
||||
if (auto e = buffer->commit())
|
||||
fatal("failed to write the output file: " + toString(std::move(e)));
|
||||
@ -1205,9 +1208,11 @@ void Writer::assignAddresses() {
|
||||
sizeOfHeaders +=
|
||||
config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
|
||||
sizeOfHeaders = alignTo(sizeOfHeaders, config->fileAlign);
|
||||
uint64_t rva = pageSize; // The first page is kept unmapped.
|
||||
fileSize = sizeOfHeaders;
|
||||
|
||||
// The first page is kept unmapped.
|
||||
uint64_t rva = alignTo(sizeOfHeaders, config->align);
|
||||
|
||||
for (OutputSection *sec : outputSections) {
|
||||
if (sec == relocSec)
|
||||
addBaserels();
|
||||
@ -1237,10 +1242,10 @@ void Writer::assignAddresses() {
|
||||
sec->header.SizeOfRawData = rawSize;
|
||||
if (rawSize != 0)
|
||||
sec->header.PointerToRawData = fileSize;
|
||||
rva += alignTo(virtualSize, pageSize);
|
||||
rva += alignTo(virtualSize, config->align);
|
||||
fileSize += alignTo(rawSize, config->fileAlign);
|
||||
}
|
||||
sizeOfImage = alignTo(rva, pageSize);
|
||||
sizeOfImage = alignTo(rva, config->align);
|
||||
|
||||
// Assign addresses to sections in MergeChunks.
|
||||
for (MergeChunk *mc : MergeChunk::instances)
|
||||
@ -1309,7 +1314,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
|
||||
pe->MinorLinkerVersion = 0;
|
||||
|
||||
pe->ImageBase = config->imageBase;
|
||||
pe->SectionAlignment = pageSize;
|
||||
pe->SectionAlignment = config->align;
|
||||
pe->FileAlignment = config->fileAlign;
|
||||
pe->MajorImageVersion = config->majorImageVersion;
|
||||
pe->MinorImageVersion = config->minorImageVersion;
|
||||
|
@ -190,6 +190,13 @@ bool PPC::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
|
||||
RelExpr PPC::getRelExpr(RelType type, const Symbol &s,
|
||||
const uint8_t *loc) const {
|
||||
switch (type) {
|
||||
case R_PPC_NONE:
|
||||
return R_NONE;
|
||||
case R_PPC_ADDR16_HA:
|
||||
case R_PPC_ADDR16_HI:
|
||||
case R_PPC_ADDR16_LO:
|
||||
case R_PPC_ADDR32:
|
||||
return R_ABS;
|
||||
case R_PPC_DTPREL16:
|
||||
case R_PPC_DTPREL16_HA:
|
||||
case R_PPC_DTPREL16_HI:
|
||||
@ -227,7 +234,9 @@ RelExpr PPC::getRelExpr(RelType type, const Symbol &s,
|
||||
case R_PPC_TPREL16_HI:
|
||||
return R_TLS;
|
||||
default:
|
||||
return R_ABS;
|
||||
error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
|
||||
") against symbol " + toString(s));
|
||||
return R_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,7 +328,7 @@ void PPC::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
|
||||
llvm_unreachable("unknown relocation");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,6 +532,21 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
|
||||
RelExpr PPC64::getRelExpr(RelType type, const Symbol &s,
|
||||
const uint8_t *loc) const {
|
||||
switch (type) {
|
||||
case R_PPC64_NONE:
|
||||
return R_NONE;
|
||||
case R_PPC64_ADDR16:
|
||||
case R_PPC64_ADDR16_DS:
|
||||
case R_PPC64_ADDR16_HA:
|
||||
case R_PPC64_ADDR16_HI:
|
||||
case R_PPC64_ADDR16_HIGHER:
|
||||
case R_PPC64_ADDR16_HIGHERA:
|
||||
case R_PPC64_ADDR16_HIGHEST:
|
||||
case R_PPC64_ADDR16_HIGHESTA:
|
||||
case R_PPC64_ADDR16_LO:
|
||||
case R_PPC64_ADDR16_LO_DS:
|
||||
case R_PPC64_ADDR32:
|
||||
case R_PPC64_ADDR64:
|
||||
return R_ABS;
|
||||
case R_PPC64_GOT16:
|
||||
case R_PPC64_GOT16_DS:
|
||||
case R_PPC64_GOT16_HA:
|
||||
@ -554,6 +569,7 @@ RelExpr PPC64::getRelExpr(RelType type, const Symbol &s,
|
||||
return R_PPC64_CALL_PLT;
|
||||
case R_PPC64_REL16_LO:
|
||||
case R_PPC64_REL16_HA:
|
||||
case R_PPC64_REL16_HI:
|
||||
case R_PPC64_REL32:
|
||||
case R_PPC64_REL64:
|
||||
return R_PC;
|
||||
@ -607,7 +623,9 @@ RelExpr PPC64::getRelExpr(RelType type, const Symbol &s,
|
||||
case R_PPC64_TLS:
|
||||
return R_TLSIE_HINT;
|
||||
default:
|
||||
return R_ABS;
|
||||
error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
|
||||
") against symbol " + toString(s));
|
||||
return R_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,7 +888,7 @@ void PPC64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
|
||||
write64(loc, val - dynamicThreadPointerOffset);
|
||||
break;
|
||||
default:
|
||||
error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
|
||||
llvm_unreachable("unknown relocation");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1144,7 +1144,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) {
|
||||
Archive::Child c =
|
||||
CHECK(sym.getMember(), toString(this) +
|
||||
": could not get the member for symbol " +
|
||||
sym.getName());
|
||||
toELFString(sym));
|
||||
|
||||
if (!seen.insert(c.getChildOffset()).second)
|
||||
return;
|
||||
@ -1153,7 +1153,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) {
|
||||
CHECK(c.getMemoryBufferRef(),
|
||||
toString(this) +
|
||||
": could not get the buffer for the member defining symbol " +
|
||||
sym.getName());
|
||||
toELFString(sym));
|
||||
|
||||
if (tar && c.getParent()->isThin())
|
||||
tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer());
|
||||
|
@ -42,6 +42,20 @@ Defined *ElfSym::relaIpltEnd;
|
||||
Defined *ElfSym::riscvGlobalPointer;
|
||||
Defined *ElfSym::tlsModuleBase;
|
||||
|
||||
// Returns a symbol for an error message.
|
||||
static std::string demangle(StringRef symName) {
|
||||
if (config->demangle)
|
||||
if (Optional<std::string> s = demangleItanium(symName))
|
||||
return *s;
|
||||
return symName;
|
||||
}
|
||||
namespace lld {
|
||||
std::string toString(const Symbol &b) { return demangle(b.getName()); }
|
||||
std::string toELFString(const Archive::Symbol &b) {
|
||||
return demangle(b.getName());
|
||||
}
|
||||
} // namespace lld
|
||||
|
||||
static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
|
||||
switch (sym.kind()) {
|
||||
case Symbol::DefinedKind: {
|
||||
@ -250,12 +264,13 @@ void Symbol::fetch() const {
|
||||
}
|
||||
|
||||
MemoryBufferRef LazyArchive::getMemberBuffer() {
|
||||
Archive::Child c = CHECK(
|
||||
sym.getMember(), "could not get the member for symbol " + sym.getName());
|
||||
Archive::Child c =
|
||||
CHECK(sym.getMember(),
|
||||
"could not get the member for symbol " + toELFString(sym));
|
||||
|
||||
return CHECK(c.getMemoryBufferRef(),
|
||||
"could not get the buffer for the member defining symbol " +
|
||||
sym.getName());
|
||||
toELFString(sym));
|
||||
}
|
||||
|
||||
uint8_t Symbol::computeBinding() const {
|
||||
@ -331,14 +346,6 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
|
||||
report(": unable to order discarded symbol: ");
|
||||
}
|
||||
|
||||
// Returns a symbol for an error message.
|
||||
std::string lld::toString(const Symbol &b) {
|
||||
if (config->demangle)
|
||||
if (Optional<std::string> s = demangleItanium(b.getName()))
|
||||
return *s;
|
||||
return b.getName();
|
||||
}
|
||||
|
||||
static uint8_t getMinVisibility(uint8_t va, uint8_t vb) {
|
||||
if (va == STV_DEFAULT)
|
||||
return vb;
|
||||
|
@ -33,7 +33,11 @@ class Undefined;
|
||||
} // namespace elf
|
||||
|
||||
std::string toString(const elf::Symbol &);
|
||||
std::string toString(const elf::InputFile *);
|
||||
|
||||
// There are two different ways to convert an Archive::Symbol to a string:
|
||||
// One for Microsoft name mangling and one for Itanium name mangling.
|
||||
// Call the functions toCOFFString and toELFString, not just toString.
|
||||
std::string toELFString(const elf::Archive::Symbol &);
|
||||
|
||||
namespace elf {
|
||||
|
||||
|
@ -5,11 +5,6 @@ lld 9.0.0 Release Notes
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
.. warning::
|
||||
These are in-progress notes for the upcoming LLVM 9.0.0 release.
|
||||
Release notes for previous releases can be found on
|
||||
`the Download Page <https://releases.llvm.org/download.html>`_.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
@ -37,8 +32,6 @@ ELF Improvements
|
||||
into corresponding PT_MIPS_REGINFO, PT_MIPS_OPTIONS, and PT_MIPS_ABIFLAGS
|
||||
segments.
|
||||
|
||||
* ...
|
||||
|
||||
COFF Improvements
|
||||
-----------------
|
||||
|
||||
@ -51,6 +44,12 @@ COFF Improvements
|
||||
input files define resources with the same type, name, and language.
|
||||
This can be demoted to a warning using ``/force:multipleres``.
|
||||
|
||||
* lld-link now rejects more than one resource obj input files, matching
|
||||
link.exe. Previously, lld-link would silently ignore all but one.
|
||||
If you hit this: Don't pass resource obj files to the linker, instead pass
|
||||
res files to the linker directly. Don't put res files in static libraries,
|
||||
pass them on the command line.
|
||||
|
||||
* Having more than two ``/natvis:`` now works correctly; it used to not
|
||||
work for larger binaries before.
|
||||
|
||||
@ -70,8 +69,6 @@ COFF Improvements
|
||||
* The generated thunks for delayimports now share the majority of code
|
||||
among thunks, significantly reducing the overhead of using delayimport
|
||||
|
||||
* ...
|
||||
|
||||
MinGW Improvements
|
||||
------------------
|
||||
|
||||
@ -89,13 +86,3 @@ MinGW Improvements
|
||||
name, with the new option ``-pdb=`` with an empty value to the option.
|
||||
(The old existing syntax ``-pdb <filename>`` was more cumbersome to use
|
||||
with an empty parameter value.)
|
||||
|
||||
MachO Improvements
|
||||
------------------
|
||||
|
||||
* Item 1.
|
||||
|
||||
WebAssembly Improvements
|
||||
------------------------
|
||||
|
||||
* ...
|
||||
|
@ -6,5 +6,5 @@
|
||||
#define LLD_VERSION_MINOR 0
|
||||
|
||||
// <Upstream revision at import>-<Local identifier in __FreeBSD_version style>
|
||||
#define LLD_REVISION "369369-1300004"
|
||||
#define LLD_REVISION "370514-1300004"
|
||||
#define LLD_REPOSITORY "FreeBSD"
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* $FreeBSD$ */
|
||||
#define LLVM_REVISION "369369"
|
||||
#define LLVM_REVISION "370514"
|
||||
#define LLVM_REPOSITORY "https://llvm.org/svn/llvm-project/llvm/branches/release_90"
|
||||
|
Loading…
Reference in New Issue
Block a user