Merge llvm, clang, compiler-rt, libc++, lld and lldb release_40 branch
r292951, and update build glue.
This commit is contained in:
commit
f8496407cb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang400-import/; revision=312719
@ -115,7 +115,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _LIBCPP_CLANG_VER
|
#ifndef _LIBCPP_CLANG_VER
|
||||||
#define _LIBCPP_CLANG_VER 0
|
# define _LIBCPP_CLANG_VER 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: ABI detection should be done via compiler builtin macros. This
|
// FIXME: ABI detection should be done via compiler builtin macros. This
|
||||||
@ -845,7 +845,7 @@ template <unsigned> struct __static_assert_check {};
|
|||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
|
# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
|
||||||
defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
|
defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
|
||||||
# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIROMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
||||||
# endif
|
# endif
|
||||||
# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||||
# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||||
|
@ -512,7 +512,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Metadata *getFnMetadataByID(unsigned ID) {
|
Metadata *getFnMetadataByID(unsigned ID) {
|
||||||
return MDLoader->getMetadataFwdRef(ID);
|
return MDLoader->getMetadataFwdRefOrLoad(ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBlock *getBasicBlock(unsigned ID) const {
|
BasicBlock *getBasicBlock(unsigned ID) const {
|
||||||
|
@ -485,8 +485,21 @@ class MetadataLoader::MetadataLoaderImpl {
|
|||||||
Error parseMetadata(bool ModuleLevel);
|
Error parseMetadata(bool ModuleLevel);
|
||||||
|
|
||||||
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
|
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
|
||||||
Metadata *getMetadataFwdRef(unsigned Idx) {
|
|
||||||
return MetadataList.getMetadataFwdRef(Idx);
|
Metadata *getMetadataFwdRefOrLoad(unsigned ID) {
|
||||||
|
if (ID < MDStringRef.size())
|
||||||
|
return lazyLoadOneMDString(ID);
|
||||||
|
if (auto *MD = MetadataList.lookup(ID))
|
||||||
|
return MD;
|
||||||
|
// If lazy-loading is enabled, we try recursively to load the operand
|
||||||
|
// instead of creating a temporary.
|
||||||
|
if (ID < (MDStringRef.size() + GlobalMetadataBitPosIndex.size())) {
|
||||||
|
PlaceholderQueue Placeholders;
|
||||||
|
lazyLoadOneMetadata(ID, Placeholders);
|
||||||
|
resolveForwardRefsAndPlaceholders(Placeholders);
|
||||||
|
return MetadataList.lookup(ID);
|
||||||
|
}
|
||||||
|
return MetadataList.getMetadataFwdRef(ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
MDNode *getMDNodeFwdRefOrNull(unsigned Idx) {
|
MDNode *getMDNodeFwdRefOrNull(unsigned Idx) {
|
||||||
@ -1727,8 +1740,8 @@ bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }
|
|||||||
|
|
||||||
/// Return the given metadata, creating a replaceable forward reference if
|
/// Return the given metadata, creating a replaceable forward reference if
|
||||||
/// necessary.
|
/// necessary.
|
||||||
Metadata *MetadataLoader::getMetadataFwdRef(unsigned Idx) {
|
Metadata *MetadataLoader::getMetadataFwdRefOrLoad(unsigned Idx) {
|
||||||
return Pimpl->getMetadataFwdRef(Idx);
|
return Pimpl->getMetadataFwdRefOrLoad(Idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) {
|
MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) {
|
||||||
|
@ -63,7 +63,7 @@ class MetadataLoader {
|
|||||||
|
|
||||||
/// Return the given metadata, creating a replaceable forward reference if
|
/// Return the given metadata, creating a replaceable forward reference if
|
||||||
/// necessary.
|
/// necessary.
|
||||||
Metadata *getMetadataFwdRef(unsigned Idx);
|
Metadata *getMetadataFwdRefOrLoad(unsigned Idx);
|
||||||
|
|
||||||
MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
|
MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
|
||||||
|
|
||||||
|
@ -687,9 +687,30 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
|
|||||||
MachineInstrBuilder MIB;
|
MachineInstrBuilder MIB;
|
||||||
DebugLoc DL = I->getDebugLoc();
|
DebugLoc DL = I->getDebugLoc();
|
||||||
MachineBasicBlock *MBB = I->getParent();
|
MachineBasicBlock *MBB = I->getParent();
|
||||||
|
MachineOperand RegOp0 = getLdStRegOp(*RtMI);
|
||||||
|
MachineOperand RegOp1 = getLdStRegOp(*Rt2MI);
|
||||||
|
// Kill flags may become invalid when moving stores for pairing.
|
||||||
|
if (RegOp0.isUse()) {
|
||||||
|
if (!MergeForward) {
|
||||||
|
// Clear kill flags on store if moving upwards. Example:
|
||||||
|
// STRWui %w0, ...
|
||||||
|
// USE %w1
|
||||||
|
// STRWui kill %w1 ; need to clear kill flag when moving STRWui upwards
|
||||||
|
RegOp0.setIsKill(false);
|
||||||
|
RegOp1.setIsKill(false);
|
||||||
|
} else {
|
||||||
|
// Clear kill flags of the first stores register. Example:
|
||||||
|
// STRWui %w1, ...
|
||||||
|
// USE kill %w1 ; need to clear kill flag when moving STRWui downwards
|
||||||
|
// STRW %w0
|
||||||
|
unsigned Reg = getLdStRegOp(*I).getReg();
|
||||||
|
for (MachineInstr &MI : make_range(std::next(I), Paired))
|
||||||
|
MI.clearRegisterKills(Reg, TRI);
|
||||||
|
}
|
||||||
|
}
|
||||||
MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingPairOpcode(Opc)))
|
MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingPairOpcode(Opc)))
|
||||||
.addOperand(getLdStRegOp(*RtMI))
|
.addOperand(RegOp0)
|
||||||
.addOperand(getLdStRegOp(*Rt2MI))
|
.addOperand(RegOp1)
|
||||||
.addOperand(BaseRegOp)
|
.addOperand(BaseRegOp)
|
||||||
.addImm(OffsetImm)
|
.addImm(OffsetImm)
|
||||||
.setMemRefs(I->mergeMemRefsWith(*Paired));
|
.setMemRefs(I->mergeMemRefsWith(*Paired));
|
||||||
|
@ -97,171 +97,6 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMTargetLowering::InitLibcallCallingConvs() {
|
|
||||||
// The builtins on ARM always use AAPCS, irrespective of wheter C is AAPCS or
|
|
||||||
// AAPCS_VFP.
|
|
||||||
for (const auto LC : {
|
|
||||||
RTLIB::SHL_I16,
|
|
||||||
RTLIB::SHL_I32,
|
|
||||||
RTLIB::SHL_I64,
|
|
||||||
RTLIB::SHL_I128,
|
|
||||||
RTLIB::SRL_I16,
|
|
||||||
RTLIB::SRL_I32,
|
|
||||||
RTLIB::SRL_I64,
|
|
||||||
RTLIB::SRL_I128,
|
|
||||||
RTLIB::SRA_I16,
|
|
||||||
RTLIB::SRA_I32,
|
|
||||||
RTLIB::SRA_I64,
|
|
||||||
RTLIB::SRA_I128,
|
|
||||||
RTLIB::MUL_I8,
|
|
||||||
RTLIB::MUL_I16,
|
|
||||||
RTLIB::MUL_I32,
|
|
||||||
RTLIB::MUL_I64,
|
|
||||||
RTLIB::MUL_I128,
|
|
||||||
RTLIB::MULO_I32,
|
|
||||||
RTLIB::MULO_I64,
|
|
||||||
RTLIB::MULO_I128,
|
|
||||||
RTLIB::SDIV_I8,
|
|
||||||
RTLIB::SDIV_I16,
|
|
||||||
RTLIB::SDIV_I32,
|
|
||||||
RTLIB::SDIV_I64,
|
|
||||||
RTLIB::SDIV_I128,
|
|
||||||
RTLIB::UDIV_I8,
|
|
||||||
RTLIB::UDIV_I16,
|
|
||||||
RTLIB::UDIV_I32,
|
|
||||||
RTLIB::UDIV_I64,
|
|
||||||
RTLIB::UDIV_I128,
|
|
||||||
RTLIB::SREM_I8,
|
|
||||||
RTLIB::SREM_I16,
|
|
||||||
RTLIB::SREM_I32,
|
|
||||||
RTLIB::SREM_I64,
|
|
||||||
RTLIB::SREM_I128,
|
|
||||||
RTLIB::UREM_I8,
|
|
||||||
RTLIB::UREM_I16,
|
|
||||||
RTLIB::UREM_I32,
|
|
||||||
RTLIB::UREM_I64,
|
|
||||||
RTLIB::UREM_I128,
|
|
||||||
RTLIB::SDIVREM_I8,
|
|
||||||
RTLIB::SDIVREM_I16,
|
|
||||||
RTLIB::SDIVREM_I32,
|
|
||||||
RTLIB::SDIVREM_I64,
|
|
||||||
RTLIB::SDIVREM_I128,
|
|
||||||
RTLIB::UDIVREM_I8,
|
|
||||||
RTLIB::UDIVREM_I16,
|
|
||||||
RTLIB::UDIVREM_I32,
|
|
||||||
RTLIB::UDIVREM_I64,
|
|
||||||
RTLIB::UDIVREM_I128,
|
|
||||||
RTLIB::NEG_I32,
|
|
||||||
RTLIB::NEG_I64,
|
|
||||||
RTLIB::ADD_F32,
|
|
||||||
RTLIB::ADD_F64,
|
|
||||||
RTLIB::ADD_F80,
|
|
||||||
RTLIB::ADD_F128,
|
|
||||||
RTLIB::SUB_F32,
|
|
||||||
RTLIB::SUB_F64,
|
|
||||||
RTLIB::SUB_F80,
|
|
||||||
RTLIB::SUB_F128,
|
|
||||||
RTLIB::MUL_F32,
|
|
||||||
RTLIB::MUL_F64,
|
|
||||||
RTLIB::MUL_F80,
|
|
||||||
RTLIB::MUL_F128,
|
|
||||||
RTLIB::DIV_F32,
|
|
||||||
RTLIB::DIV_F64,
|
|
||||||
RTLIB::DIV_F80,
|
|
||||||
RTLIB::DIV_F128,
|
|
||||||
RTLIB::POWI_F32,
|
|
||||||
RTLIB::POWI_F64,
|
|
||||||
RTLIB::POWI_F80,
|
|
||||||
RTLIB::POWI_F128,
|
|
||||||
RTLIB::FPEXT_F64_F128,
|
|
||||||
RTLIB::FPEXT_F32_F128,
|
|
||||||
RTLIB::FPEXT_F32_F64,
|
|
||||||
RTLIB::FPEXT_F16_F32,
|
|
||||||
RTLIB::FPROUND_F32_F16,
|
|
||||||
RTLIB::FPROUND_F64_F16,
|
|
||||||
RTLIB::FPROUND_F80_F16,
|
|
||||||
RTLIB::FPROUND_F128_F16,
|
|
||||||
RTLIB::FPROUND_F64_F32,
|
|
||||||
RTLIB::FPROUND_F80_F32,
|
|
||||||
RTLIB::FPROUND_F128_F32,
|
|
||||||
RTLIB::FPROUND_F80_F64,
|
|
||||||
RTLIB::FPROUND_F128_F64,
|
|
||||||
RTLIB::FPTOSINT_F32_I32,
|
|
||||||
RTLIB::FPTOSINT_F32_I64,
|
|
||||||
RTLIB::FPTOSINT_F32_I128,
|
|
||||||
RTLIB::FPTOSINT_F64_I32,
|
|
||||||
RTLIB::FPTOSINT_F64_I64,
|
|
||||||
RTLIB::FPTOSINT_F64_I128,
|
|
||||||
RTLIB::FPTOSINT_F80_I32,
|
|
||||||
RTLIB::FPTOSINT_F80_I64,
|
|
||||||
RTLIB::FPTOSINT_F80_I128,
|
|
||||||
RTLIB::FPTOSINT_F128_I32,
|
|
||||||
RTLIB::FPTOSINT_F128_I64,
|
|
||||||
RTLIB::FPTOSINT_F128_I128,
|
|
||||||
RTLIB::FPTOUINT_F32_I32,
|
|
||||||
RTLIB::FPTOUINT_F32_I64,
|
|
||||||
RTLIB::FPTOUINT_F32_I128,
|
|
||||||
RTLIB::FPTOUINT_F64_I32,
|
|
||||||
RTLIB::FPTOUINT_F64_I64,
|
|
||||||
RTLIB::FPTOUINT_F64_I128,
|
|
||||||
RTLIB::FPTOUINT_F80_I32,
|
|
||||||
RTLIB::FPTOUINT_F80_I64,
|
|
||||||
RTLIB::FPTOUINT_F80_I128,
|
|
||||||
RTLIB::FPTOUINT_F128_I32,
|
|
||||||
RTLIB::FPTOUINT_F128_I64,
|
|
||||||
RTLIB::FPTOUINT_F128_I128,
|
|
||||||
RTLIB::SINTTOFP_I32_F32,
|
|
||||||
RTLIB::SINTTOFP_I32_F64,
|
|
||||||
RTLIB::SINTTOFP_I32_F80,
|
|
||||||
RTLIB::SINTTOFP_I32_F128,
|
|
||||||
RTLIB::SINTTOFP_I64_F32,
|
|
||||||
RTLIB::SINTTOFP_I64_F64,
|
|
||||||
RTLIB::SINTTOFP_I64_F80,
|
|
||||||
RTLIB::SINTTOFP_I64_F128,
|
|
||||||
RTLIB::SINTTOFP_I128_F32,
|
|
||||||
RTLIB::SINTTOFP_I128_F64,
|
|
||||||
RTLIB::SINTTOFP_I128_F80,
|
|
||||||
RTLIB::SINTTOFP_I128_F128,
|
|
||||||
RTLIB::UINTTOFP_I32_F32,
|
|
||||||
RTLIB::UINTTOFP_I32_F64,
|
|
||||||
RTLIB::UINTTOFP_I32_F80,
|
|
||||||
RTLIB::UINTTOFP_I32_F128,
|
|
||||||
RTLIB::UINTTOFP_I64_F32,
|
|
||||||
RTLIB::UINTTOFP_I64_F64,
|
|
||||||
RTLIB::UINTTOFP_I64_F80,
|
|
||||||
RTLIB::UINTTOFP_I64_F128,
|
|
||||||
RTLIB::UINTTOFP_I128_F32,
|
|
||||||
RTLIB::UINTTOFP_I128_F64,
|
|
||||||
RTLIB::UINTTOFP_I128_F80,
|
|
||||||
RTLIB::UINTTOFP_I128_F128,
|
|
||||||
RTLIB::OEQ_F32,
|
|
||||||
RTLIB::OEQ_F64,
|
|
||||||
RTLIB::OEQ_F128,
|
|
||||||
RTLIB::UNE_F32,
|
|
||||||
RTLIB::UNE_F64,
|
|
||||||
RTLIB::UNE_F128,
|
|
||||||
RTLIB::OGE_F32,
|
|
||||||
RTLIB::OGE_F64,
|
|
||||||
RTLIB::OGE_F128,
|
|
||||||
RTLIB::OLT_F32,
|
|
||||||
RTLIB::OLT_F64,
|
|
||||||
RTLIB::OLT_F128,
|
|
||||||
RTLIB::OLE_F32,
|
|
||||||
RTLIB::OLE_F64,
|
|
||||||
RTLIB::OLE_F128,
|
|
||||||
RTLIB::OGT_F32,
|
|
||||||
RTLIB::OGT_F64,
|
|
||||||
RTLIB::OGT_F128,
|
|
||||||
RTLIB::UO_F32,
|
|
||||||
RTLIB::UO_F64,
|
|
||||||
RTLIB::UO_F128,
|
|
||||||
RTLIB::O_F32,
|
|
||||||
RTLIB::O_F64,
|
|
||||||
RTLIB::O_F128,
|
|
||||||
})
|
|
||||||
setLibcallCallingConv(LC, CallingConv::ARM_AAPCS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The APCS parameter registers.
|
// The APCS parameter registers.
|
||||||
static const MCPhysReg GPRArgRegs[] = {
|
static const MCPhysReg GPRArgRegs[] = {
|
||||||
ARM::R0, ARM::R1, ARM::R2, ARM::R3
|
ARM::R0, ARM::R1, ARM::R2, ARM::R3
|
||||||
@ -349,7 +184,22 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
|||||||
|
|
||||||
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
|
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
|
||||||
|
|
||||||
InitLibcallCallingConvs();
|
if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetIOS() &&
|
||||||
|
!Subtarget->isTargetWatchOS()) {
|
||||||
|
const auto &E = Subtarget->getTargetTriple().getEnvironment();
|
||||||
|
|
||||||
|
bool IsHFTarget = E == Triple::EABIHF || E == Triple::GNUEABIHF ||
|
||||||
|
E == Triple::MuslEABIHF;
|
||||||
|
// Windows is a special case. Technically, we will replace all of the "GNU"
|
||||||
|
// calls with calls to MSVCRT if appropriate and adjust the calling
|
||||||
|
// convention then.
|
||||||
|
IsHFTarget = IsHFTarget || Subtarget->isTargetWindows();
|
||||||
|
|
||||||
|
for (int LCID = 0; LCID < RTLIB::UNKNOWN_LIBCALL; ++LCID)
|
||||||
|
setLibcallCallingConv(static_cast<RTLIB::Libcall>(LCID),
|
||||||
|
IsHFTarget ? CallingConv::ARM_AAPCS_VFP
|
||||||
|
: CallingConv::ARM_AAPCS);
|
||||||
|
}
|
||||||
|
|
||||||
if (Subtarget->isTargetMachO()) {
|
if (Subtarget->isTargetMachO()) {
|
||||||
// Uses VFP for Thumb libfuncs if available.
|
// Uses VFP for Thumb libfuncs if available.
|
||||||
|
@ -538,8 +538,6 @@ class InstrItineraryData;
|
|||||||
|
|
||||||
bool HasStandaloneRem = true;
|
bool HasStandaloneRem = true;
|
||||||
|
|
||||||
void InitLibcallCallingConvs();
|
|
||||||
|
|
||||||
void addTypeForNEON(MVT VT, MVT PromotedLdStVT, MVT PromotedBitwiseVT);
|
void addTypeForNEON(MVT VT, MVT PromotedLdStVT, MVT PromotedBitwiseVT);
|
||||||
void addDRTypeForNEON(MVT VT);
|
void addDRTypeForNEON(MVT VT);
|
||||||
void addQRTypeForNEON(MVT VT);
|
void addQRTypeForNEON(MVT VT);
|
||||||
|
@ -600,6 +600,22 @@ class AddressSanitizerModule : public ModulePass {
|
|||||||
void initializeCallbacks(Module &M);
|
void initializeCallbacks(Module &M);
|
||||||
|
|
||||||
bool InstrumentGlobals(IRBuilder<> &IRB, Module &M);
|
bool InstrumentGlobals(IRBuilder<> &IRB, Module &M);
|
||||||
|
void InstrumentGlobalsCOFF(IRBuilder<> &IRB, Module &M,
|
||||||
|
ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||||
|
ArrayRef<Constant *> MetadataInitializers);
|
||||||
|
void InstrumentGlobalsMachO(IRBuilder<> &IRB, Module &M,
|
||||||
|
ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||||
|
ArrayRef<Constant *> MetadataInitializers);
|
||||||
|
void
|
||||||
|
InstrumentGlobalsWithMetadataArray(IRBuilder<> &IRB, Module &M,
|
||||||
|
ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||||
|
ArrayRef<Constant *> MetadataInitializers);
|
||||||
|
|
||||||
|
GlobalVariable *CreateMetadataGlobal(Module &M, Constant *Initializer,
|
||||||
|
StringRef OriginalName);
|
||||||
|
void SetComdatForGlobalMetadata(GlobalVariable *G, GlobalVariable *Metadata);
|
||||||
|
IRBuilder<> CreateAsanModuleDtor(Module &M);
|
||||||
|
|
||||||
bool ShouldInstrumentGlobal(GlobalVariable *G);
|
bool ShouldInstrumentGlobal(GlobalVariable *G);
|
||||||
bool ShouldUseMachOGlobalsSection() const;
|
bool ShouldUseMachOGlobalsSection() const;
|
||||||
StringRef getGlobalMetadataSection() const;
|
StringRef getGlobalMetadataSection() const;
|
||||||
@ -1553,17 +1569,173 @@ void AddressSanitizerModule::initializeCallbacks(Module &M) {
|
|||||||
|
|
||||||
// Declare the functions that find globals in a shared object and then invoke
|
// Declare the functions that find globals in a shared object and then invoke
|
||||||
// the (un)register function on them.
|
// the (un)register function on them.
|
||||||
AsanRegisterImageGlobals = checkSanitizerInterfaceFunction(
|
AsanRegisterImageGlobals =
|
||||||
M.getOrInsertFunction(kAsanRegisterImageGlobalsName,
|
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||||
IRB.getVoidTy(), IntptrTy, nullptr));
|
kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
|
||||||
AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
||||||
|
|
||||||
AsanUnregisterImageGlobals = checkSanitizerInterfaceFunction(
|
AsanUnregisterImageGlobals =
|
||||||
M.getOrInsertFunction(kAsanUnregisterImageGlobalsName,
|
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||||
IRB.getVoidTy(), IntptrTy, nullptr));
|
kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
|
||||||
AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put the metadata and the instrumented global in the same group. This ensures
|
||||||
|
// that the metadata is discarded if the instrumented global is discarded.
|
||||||
|
void AddressSanitizerModule::SetComdatForGlobalMetadata(
|
||||||
|
GlobalVariable *G, GlobalVariable *Metadata) {
|
||||||
|
Module &M = *G->getParent();
|
||||||
|
Comdat *C = G->getComdat();
|
||||||
|
if (!C) {
|
||||||
|
if (!G->hasName()) {
|
||||||
|
// If G is unnamed, it must be internal. Give it an artificial name
|
||||||
|
// so we can put it in a comdat.
|
||||||
|
assert(G->hasLocalLinkage());
|
||||||
|
G->setName(Twine(kAsanGenPrefix) + "_anon_global");
|
||||||
|
}
|
||||||
|
C = M.getOrInsertComdat(G->getName());
|
||||||
|
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
|
||||||
|
if (TargetTriple.isOSBinFormatCOFF())
|
||||||
|
C->setSelectionKind(Comdat::NoDuplicates);
|
||||||
|
G->setComdat(C);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(G->hasComdat());
|
||||||
|
Metadata->setComdat(G->getComdat());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a separate metadata global and put it in the appropriate ASan
|
||||||
|
// global registration section.
|
||||||
|
GlobalVariable *
|
||||||
|
AddressSanitizerModule::CreateMetadataGlobal(Module &M, Constant *Initializer,
|
||||||
|
StringRef OriginalName) {
|
||||||
|
GlobalVariable *Metadata =
|
||||||
|
new GlobalVariable(M, Initializer->getType(), false,
|
||||||
|
GlobalVariable::InternalLinkage, Initializer,
|
||||||
|
Twine("__asan_global_") +
|
||||||
|
GlobalValue::getRealLinkageName(OriginalName));
|
||||||
|
Metadata->setSection(getGlobalMetadataSection());
|
||||||
|
return Metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
IRBuilder<> AddressSanitizerModule::CreateAsanModuleDtor(Module &M) {
|
||||||
|
Function *AsanDtorFunction =
|
||||||
|
Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
|
||||||
|
GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
|
||||||
|
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
|
||||||
|
appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
|
||||||
|
|
||||||
|
return IRBuilder<>(ReturnInst::Create(*C, AsanDtorBB));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressSanitizerModule::InstrumentGlobalsCOFF(
|
||||||
|
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||||
|
ArrayRef<Constant *> MetadataInitializers) {
|
||||||
|
assert(ExtendedGlobals.size() == MetadataInitializers.size());
|
||||||
|
auto &DL = M.getDataLayout();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
|
||||||
|
Constant *Initializer = MetadataInitializers[i];
|
||||||
|
GlobalVariable *G = ExtendedGlobals[i];
|
||||||
|
GlobalVariable *Metadata =
|
||||||
|
CreateMetadataGlobal(M, Initializer, G->getName());
|
||||||
|
|
||||||
|
// The MSVC linker always inserts padding when linking incrementally. We
|
||||||
|
// cope with that by aligning each struct to its size, which must be a power
|
||||||
|
// of two.
|
||||||
|
unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->getType());
|
||||||
|
assert(isPowerOf2_32(SizeOfGlobalStruct) &&
|
||||||
|
"global metadata will not be padded appropriately");
|
||||||
|
Metadata->setAlignment(SizeOfGlobalStruct);
|
||||||
|
|
||||||
|
SetComdatForGlobalMetadata(G, Metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressSanitizerModule::InstrumentGlobalsMachO(
|
||||||
|
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||||
|
ArrayRef<Constant *> MetadataInitializers) {
|
||||||
|
assert(ExtendedGlobals.size() == MetadataInitializers.size());
|
||||||
|
|
||||||
|
// On recent Mach-O platforms, use a structure which binds the liveness of
|
||||||
|
// the global variable to the metadata struct. Keep the list of "Liveness" GV
|
||||||
|
// created to be added to llvm.compiler.used
|
||||||
|
StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
|
||||||
|
SmallVector<GlobalValue *, 16> LivenessGlobals(ExtendedGlobals.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
|
||||||
|
Constant *Initializer = MetadataInitializers[i];
|
||||||
|
GlobalVariable *G = ExtendedGlobals[i];
|
||||||
|
GlobalVariable *Metadata =
|
||||||
|
CreateMetadataGlobal(M, Initializer, G->getName());
|
||||||
|
|
||||||
|
// On recent Mach-O platforms, we emit the global metadata in a way that
|
||||||
|
// allows the linker to properly strip dead globals.
|
||||||
|
auto LivenessBinder = ConstantStruct::get(
|
||||||
|
LivenessTy, Initializer->getAggregateElement(0u),
|
||||||
|
ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
|
||||||
|
GlobalVariable *Liveness = new GlobalVariable(
|
||||||
|
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
|
||||||
|
Twine("__asan_binder_") + G->getName());
|
||||||
|
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
|
||||||
|
LivenessGlobals[i] = Liveness;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update llvm.compiler.used, adding the new liveness globals. This is
|
||||||
|
// needed so that during LTO these variables stay alive. The alternative
|
||||||
|
// would be to have the linker handling the LTO symbols, but libLTO
|
||||||
|
// current API does not expose access to the section for each symbol.
|
||||||
|
if (!LivenessGlobals.empty())
|
||||||
|
appendToCompilerUsed(M, LivenessGlobals);
|
||||||
|
|
||||||
|
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
|
||||||
|
// to look up the loaded image that contains it. Second, we can store in it
|
||||||
|
// whether registration has already occurred, to prevent duplicate
|
||||||
|
// registration.
|
||||||
|
//
|
||||||
|
// common linkage ensures that there is only one global per shared library.
|
||||||
|
GlobalVariable *RegisteredFlag = new GlobalVariable(
|
||||||
|
M, IntptrTy, false, GlobalVariable::CommonLinkage,
|
||||||
|
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
|
||||||
|
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
|
||||||
|
|
||||||
|
IRB.CreateCall(AsanRegisterImageGlobals,
|
||||||
|
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
||||||
|
|
||||||
|
// We also need to unregister globals at the end, e.g., when a shared library
|
||||||
|
// gets closed.
|
||||||
|
IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
|
||||||
|
IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
|
||||||
|
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressSanitizerModule::InstrumentGlobalsWithMetadataArray(
|
||||||
|
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
|
||||||
|
ArrayRef<Constant *> MetadataInitializers) {
|
||||||
|
assert(ExtendedGlobals.size() == MetadataInitializers.size());
|
||||||
|
unsigned N = ExtendedGlobals.size();
|
||||||
|
assert(N > 0);
|
||||||
|
|
||||||
|
// On platforms that don't have a custom metadata section, we emit an array
|
||||||
|
// of global metadata structures.
|
||||||
|
ArrayType *ArrayOfGlobalStructTy =
|
||||||
|
ArrayType::get(MetadataInitializers[0]->getType(), N);
|
||||||
|
auto AllGlobals = new GlobalVariable(
|
||||||
|
M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
|
||||||
|
ConstantArray::get(ArrayOfGlobalStructTy, MetadataInitializers), "");
|
||||||
|
|
||||||
|
IRB.CreateCall(AsanRegisterGlobals,
|
||||||
|
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
||||||
|
ConstantInt::get(IntptrTy, N)});
|
||||||
|
|
||||||
|
// We also need to unregister globals at the end, e.g., when a shared library
|
||||||
|
// gets closed.
|
||||||
|
IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
|
||||||
|
IRB_Dtor.CreateCall(AsanUnregisterGlobals,
|
||||||
|
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
||||||
|
ConstantInt::get(IntptrTy, N)});
|
||||||
|
}
|
||||||
|
|
||||||
// This function replaces all global variables with new variables that have
|
// This function replaces all global variables with new variables that have
|
||||||
// trailing redzones. It also creates a function that poisons
|
// trailing redzones. It also creates a function that poisons
|
||||||
// redzones and inserts this function into llvm.global_ctors.
|
// redzones and inserts this function into llvm.global_ctors.
|
||||||
@ -1580,9 +1752,6 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
|||||||
if (n == 0) return false;
|
if (n == 0) return false;
|
||||||
|
|
||||||
auto &DL = M.getDataLayout();
|
auto &DL = M.getDataLayout();
|
||||||
bool UseComdatMetadata = TargetTriple.isOSBinFormatCOFF();
|
|
||||||
bool UseMachOGlobalsSection = ShouldUseMachOGlobalsSection();
|
|
||||||
bool UseMetadataArray = !(UseComdatMetadata || UseMachOGlobalsSection);
|
|
||||||
|
|
||||||
// A global is described by a structure
|
// A global is described by a structure
|
||||||
// size_t beg;
|
// size_t beg;
|
||||||
@ -1597,19 +1766,8 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
|||||||
StructType *GlobalStructTy =
|
StructType *GlobalStructTy =
|
||||||
StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
|
StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
|
||||||
IntptrTy, IntptrTy, IntptrTy, nullptr);
|
IntptrTy, IntptrTy, IntptrTy, nullptr);
|
||||||
unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(GlobalStructTy);
|
SmallVector<GlobalVariable *, 16> NewGlobals(n);
|
||||||
assert(isPowerOf2_32(SizeOfGlobalStruct) &&
|
SmallVector<Constant *, 16> Initializers(n);
|
||||||
"global metadata will not be padded appropriately");
|
|
||||||
SmallVector<Constant *, 16> Initializers(UseMetadataArray ? n : 0);
|
|
||||||
|
|
||||||
// On recent Mach-O platforms, use a structure which binds the liveness of
|
|
||||||
// the global variable to the metadata struct. Keep the list of "Liveness" GV
|
|
||||||
// created to be added to llvm.compiler.used
|
|
||||||
StructType *LivenessTy = nullptr;
|
|
||||||
if (UseMachOGlobalsSection)
|
|
||||||
LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
|
|
||||||
SmallVector<GlobalValue *, 16> LivenessGlobals(
|
|
||||||
UseMachOGlobalsSection ? n : 0);
|
|
||||||
|
|
||||||
bool HasDynamicallyInitializedGlobals = false;
|
bool HasDynamicallyInitializedGlobals = false;
|
||||||
|
|
||||||
@ -1681,25 +1839,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
|||||||
ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true));
|
ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true));
|
||||||
NewGlobal->takeName(G);
|
NewGlobal->takeName(G);
|
||||||
G->eraseFromParent();
|
G->eraseFromParent();
|
||||||
G = NewGlobal;
|
NewGlobals[i] = NewGlobal;
|
||||||
|
|
||||||
if (UseComdatMetadata) {
|
|
||||||
// Get or create a COMDAT for G so that we can use it with our metadata.
|
|
||||||
Comdat *C = G->getComdat();
|
|
||||||
if (!C) {
|
|
||||||
if (!G->hasName()) {
|
|
||||||
// If G is unnamed, it must be internal. Give it an artificial name
|
|
||||||
// so we can put it in a comdat.
|
|
||||||
assert(G->hasLocalLinkage());
|
|
||||||
G->setName(Twine(kAsanGenPrefix) + "_anon_global");
|
|
||||||
}
|
|
||||||
C = M.getOrInsertComdat(G->getName());
|
|
||||||
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
|
|
||||||
if (TargetTriple.isOSBinFormatCOFF())
|
|
||||||
C->setSelectionKind(Comdat::NoDuplicates);
|
|
||||||
G->setComdat(C);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Constant *SourceLoc;
|
Constant *SourceLoc;
|
||||||
if (!MD.SourceLoc.empty()) {
|
if (!MD.SourceLoc.empty()) {
|
||||||
@ -1750,117 +1890,21 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
|||||||
|
|
||||||
DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
|
DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
|
||||||
|
|
||||||
// If we aren't using separate metadata globals, add it to the initializer
|
Initializers[i] = Initializer;
|
||||||
// list and continue.
|
}
|
||||||
if (UseMetadataArray) {
|
|
||||||
Initializers[i] = Initializer;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a separate metadata global and put it in the appropriate ASan
|
if (TargetTriple.isOSBinFormatCOFF()) {
|
||||||
// global registration section.
|
InstrumentGlobalsCOFF(IRB, M, NewGlobals, Initializers);
|
||||||
GlobalVariable *Metadata = new GlobalVariable(
|
} else if (ShouldUseMachOGlobalsSection()) {
|
||||||
M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
|
InstrumentGlobalsMachO(IRB, M, NewGlobals, Initializers);
|
||||||
Initializer, Twine("__asan_global_") +
|
} else {
|
||||||
GlobalValue::getRealLinkageName(G->getName()));
|
InstrumentGlobalsWithMetadataArray(IRB, M, NewGlobals, Initializers);
|
||||||
Metadata->setSection(getGlobalMetadataSection());
|
|
||||||
|
|
||||||
// We don't want any padding, but we also need a reasonable alignment.
|
|
||||||
// The MSVC linker always inserts padding when linking incrementally. We
|
|
||||||
// cope with that by aligning each struct to its size, which must be a power
|
|
||||||
// of two.
|
|
||||||
Metadata->setAlignment(SizeOfGlobalStruct);
|
|
||||||
|
|
||||||
// On platforms that support comdats, put the metadata and the
|
|
||||||
// instrumented global in the same group. This ensures that the metadata
|
|
||||||
// is discarded if the instrumented global is discarded.
|
|
||||||
if (UseComdatMetadata) {
|
|
||||||
assert(G->hasComdat());
|
|
||||||
Metadata->setComdat(G->getComdat());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
assert(UseMachOGlobalsSection);
|
|
||||||
|
|
||||||
// On recent Mach-O platforms, we emit the global metadata in a way that
|
|
||||||
// allows the linker to properly strip dead globals.
|
|
||||||
auto LivenessBinder = ConstantStruct::get(
|
|
||||||
LivenessTy, Initializer->getAggregateElement(0u),
|
|
||||||
ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
|
|
||||||
GlobalVariable *Liveness = new GlobalVariable(
|
|
||||||
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
|
|
||||||
Twine("__asan_binder_") + G->getName());
|
|
||||||
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
|
|
||||||
LivenessGlobals[i] = Liveness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create calls for poisoning before initializers run and unpoisoning after.
|
// Create calls for poisoning before initializers run and unpoisoning after.
|
||||||
if (HasDynamicallyInitializedGlobals)
|
if (HasDynamicallyInitializedGlobals)
|
||||||
createInitializerPoisonCalls(M, ModuleName);
|
createInitializerPoisonCalls(M, ModuleName);
|
||||||
|
|
||||||
// Platforms with a dedicated metadata section don't need to emit any more
|
|
||||||
// code.
|
|
||||||
if (UseComdatMetadata)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
GlobalVariable *AllGlobals = nullptr;
|
|
||||||
GlobalVariable *RegisteredFlag = nullptr;
|
|
||||||
|
|
||||||
if (UseMachOGlobalsSection) {
|
|
||||||
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
|
|
||||||
// to look up the loaded image that contains it. Second, we can store in it
|
|
||||||
// whether registration has already occurred, to prevent duplicate
|
|
||||||
// registration.
|
|
||||||
//
|
|
||||||
// common linkage ensures that there is only one global per shared library.
|
|
||||||
RegisteredFlag = new GlobalVariable(
|
|
||||||
M, IntptrTy, false, GlobalVariable::CommonLinkage,
|
|
||||||
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
|
|
||||||
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
|
|
||||||
|
|
||||||
// Update llvm.compiler.used, adding the new liveness globals. This is
|
|
||||||
// needed so that during LTO these variables stay alive. The alternative
|
|
||||||
// would be to have the linker handling the LTO symbols, but libLTO
|
|
||||||
// current API does not expose access to the section for each symbol.
|
|
||||||
if (!LivenessGlobals.empty())
|
|
||||||
appendToCompilerUsed(M, LivenessGlobals);
|
|
||||||
} else if (UseMetadataArray) {
|
|
||||||
// On platforms that don't have a custom metadata section, we emit an array
|
|
||||||
// of global metadata structures.
|
|
||||||
ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
|
|
||||||
AllGlobals = new GlobalVariable(
|
|
||||||
M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
|
|
||||||
ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a call to register the globals with the runtime.
|
|
||||||
if (UseMachOGlobalsSection) {
|
|
||||||
IRB.CreateCall(AsanRegisterImageGlobals,
|
|
||||||
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
|
||||||
} else {
|
|
||||||
IRB.CreateCall(AsanRegisterGlobals,
|
|
||||||
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
|
||||||
ConstantInt::get(IntptrTy, n)});
|
|
||||||
}
|
|
||||||
|
|
||||||
// We also need to unregister globals at the end, e.g., when a shared library
|
|
||||||
// gets closed.
|
|
||||||
Function *AsanDtorFunction =
|
|
||||||
Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
|
|
||||||
GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
|
|
||||||
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
|
|
||||||
IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
|
|
||||||
|
|
||||||
if (UseMachOGlobalsSection) {
|
|
||||||
IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
|
|
||||||
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
|
|
||||||
} else {
|
|
||||||
IRB_Dtor.CreateCall(AsanUnregisterGlobals,
|
|
||||||
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
|
|
||||||
ConstantInt::get(IntptrTy, n)});
|
|
||||||
}
|
|
||||||
|
|
||||||
appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
|
|
||||||
|
|
||||||
DEBUG(dbgs() << M);
|
DEBUG(dbgs() << M);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,8 @@ STATISTIC(NumGVNLeaderChanges, "Number of leader changes");
|
|||||||
STATISTIC(NumGVNSortedLeaderChanges, "Number of sorted leader changes");
|
STATISTIC(NumGVNSortedLeaderChanges, "Number of sorted leader changes");
|
||||||
STATISTIC(NumGVNAvoidedSortedLeaderChanges,
|
STATISTIC(NumGVNAvoidedSortedLeaderChanges,
|
||||||
"Number of avoided sorted leader changes");
|
"Number of avoided sorted leader changes");
|
||||||
|
STATISTIC(NumGVNNotMostDominatingLeader,
|
||||||
|
"Number of times a member dominated it's new classes' leader");
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// GVN Pass
|
// GVN Pass
|
||||||
@ -1073,17 +1075,20 @@ void NewGVN::moveValueToNewCongruenceClass(Instruction *I,
|
|||||||
if (I == OldClass->NextLeader.first)
|
if (I == OldClass->NextLeader.first)
|
||||||
OldClass->NextLeader = {nullptr, ~0U};
|
OldClass->NextLeader = {nullptr, ~0U};
|
||||||
|
|
||||||
// The new instruction and new class leader may either be siblings in the
|
// It's possible, though unlikely, for us to discover equivalences such
|
||||||
// dominator tree, or the new class leader should dominate the new member
|
// that the current leader does not dominate the old one.
|
||||||
// instruction. We simply check that the member instruction does not properly
|
// This statistic tracks how often this happens.
|
||||||
// dominate the new class leader.
|
// We assert on phi nodes when this happens, currently, for debugging, because
|
||||||
assert(
|
// we want to make sure we name phi node cycles properly.
|
||||||
!isa<Instruction>(NewClass->RepLeader) || !NewClass->RepLeader ||
|
if (isa<Instruction>(NewClass->RepLeader) && NewClass->RepLeader &&
|
||||||
I == NewClass->RepLeader ||
|
I != NewClass->RepLeader &&
|
||||||
!DT->properlyDominates(
|
DT->properlyDominates(
|
||||||
I->getParent(),
|
I->getParent(),
|
||||||
cast<Instruction>(NewClass->RepLeader)->getParent()) &&
|
cast<Instruction>(NewClass->RepLeader)->getParent())) {
|
||||||
"New class for instruction should not be dominated by instruction");
|
++NumGVNNotMostDominatingLeader;
|
||||||
|
assert(!isa<PHINode>(I) &&
|
||||||
|
"New class for instruction should not be dominated by instruction");
|
||||||
|
}
|
||||||
|
|
||||||
if (NewClass->RepLeader != I) {
|
if (NewClass->RepLeader != I) {
|
||||||
auto DFSNum = InstrDFS.lookup(I);
|
auto DFSNum = InstrDFS.lookup(I);
|
||||||
|
@ -1339,6 +1339,7 @@ BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n")
|
|||||||
BUILTIN(__builtin_addressof, "v*v&", "nct")
|
BUILTIN(__builtin_addressof, "v*v&", "nct")
|
||||||
BUILTIN(__builtin_operator_new, "v*z", "c")
|
BUILTIN(__builtin_operator_new, "v*z", "c")
|
||||||
BUILTIN(__builtin_operator_delete, "vv*", "n")
|
BUILTIN(__builtin_operator_delete, "vv*", "n")
|
||||||
|
BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
|
||||||
|
|
||||||
// Safestack builtins
|
// Safestack builtins
|
||||||
BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
|
BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
|
||||||
|
@ -5683,6 +5683,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
|
|||||||
case Builtin::BI__builtin_strchr:
|
case Builtin::BI__builtin_strchr:
|
||||||
case Builtin::BI__builtin_wcschr:
|
case Builtin::BI__builtin_wcschr:
|
||||||
case Builtin::BI__builtin_memchr:
|
case Builtin::BI__builtin_memchr:
|
||||||
|
case Builtin::BI__builtin_char_memchr:
|
||||||
case Builtin::BI__builtin_wmemchr: {
|
case Builtin::BI__builtin_wmemchr: {
|
||||||
if (!Visit(E->getArg(0)))
|
if (!Visit(E->getArg(0)))
|
||||||
return false;
|
return false;
|
||||||
@ -5720,6 +5721,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
|
|||||||
// Fall through.
|
// Fall through.
|
||||||
case Builtin::BImemchr:
|
case Builtin::BImemchr:
|
||||||
case Builtin::BI__builtin_memchr:
|
case Builtin::BI__builtin_memchr:
|
||||||
|
case Builtin::BI__builtin_char_memchr:
|
||||||
// memchr compares by converting both sides to unsigned char. That's also
|
// memchr compares by converting both sides to unsigned char. That's also
|
||||||
// correct for strchr if we get this far (to cope with plain char being
|
// correct for strchr if we get this far (to cope with plain char being
|
||||||
// unsigned in the strchr case).
|
// unsigned in the strchr case).
|
||||||
|
@ -1189,6 +1189,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||||||
return RValue::get(Dest.getPointer());
|
return RValue::get(Dest.getPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Builtin::BI__builtin_char_memchr:
|
||||||
|
BuiltinID = Builtin::BI__builtin_memchr;
|
||||||
|
break;
|
||||||
|
|
||||||
case Builtin::BI__builtin___memcpy_chk: {
|
case Builtin::BI__builtin___memcpy_chk: {
|
||||||
// fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
|
// fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
|
||||||
llvm::APSInt Size, DstSize;
|
llvm::APSInt Size, DstSize;
|
||||||
|
@ -1183,6 +1183,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
|
|||||||
.Case("cxx_attributes", LangOpts.CPlusPlus11)
|
.Case("cxx_attributes", LangOpts.CPlusPlus11)
|
||||||
.Case("cxx_auto_type", LangOpts.CPlusPlus11)
|
.Case("cxx_auto_type", LangOpts.CPlusPlus11)
|
||||||
.Case("cxx_constexpr", LangOpts.CPlusPlus11)
|
.Case("cxx_constexpr", LangOpts.CPlusPlus11)
|
||||||
|
.Case("cxx_constexpr_string_builtins", LangOpts.CPlusPlus11)
|
||||||
.Case("cxx_decltype", LangOpts.CPlusPlus11)
|
.Case("cxx_decltype", LangOpts.CPlusPlus11)
|
||||||
.Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
|
.Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
|
||||||
.Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
|
.Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
|
||||||
|
@ -12383,9 +12383,9 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
|
|||||||
Diag(Loc, diag::err_in_class_initializer_not_yet_parsed)
|
Diag(Loc, diag::err_in_class_initializer_not_yet_parsed)
|
||||||
<< OutermostClass << Field;
|
<< OutermostClass << Field;
|
||||||
Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed);
|
Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed);
|
||||||
|
// Recover by marking the field invalid, unless we're in a SFINAE context.
|
||||||
// Don't diagnose this again.
|
if (!isSFINAEContext())
|
||||||
Field->setInvalidDecl();
|
Field->setInvalidDecl();
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11496,7 +11496,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
|||||||
return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr);
|
return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr);
|
||||||
|
|
||||||
// Don't resolve overloads if the other type is overloadable.
|
// Don't resolve overloads if the other type is overloadable.
|
||||||
if (pty->getKind() == BuiltinType::Overload) {
|
if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload) {
|
||||||
// We can't actually test that if we still have a placeholder,
|
// We can't actually test that if we still have a placeholder,
|
||||||
// though. Fortunately, none of the exceptions we see in that
|
// though. Fortunately, none of the exceptions we see in that
|
||||||
// code below are valid when the LHS is an overload set. Note
|
// code below are valid when the LHS is an overload set. Note
|
||||||
@ -11521,17 +11521,16 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
|||||||
// An overload in the RHS can potentially be resolved by the type
|
// An overload in the RHS can potentially be resolved by the type
|
||||||
// being assigned to.
|
// being assigned to.
|
||||||
if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) {
|
if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) {
|
||||||
if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent())
|
if (getLangOpts().CPlusPlus &&
|
||||||
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
(LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent() ||
|
||||||
|
LHSExpr->getType()->isOverloadableType()))
|
||||||
if (LHSExpr->getType()->isOverloadableType())
|
|
||||||
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
||||||
|
|
||||||
return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr);
|
return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't resolve overloads if the other type is overloadable.
|
// Don't resolve overloads if the other type is overloadable.
|
||||||
if (pty->getKind() == BuiltinType::Overload &&
|
if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload &&
|
||||||
LHSExpr->getType()->isOverloadableType())
|
LHSExpr->getType()->isOverloadableType())
|
||||||
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
|
||||||
|
|
||||||
|
@ -14,9 +14,12 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static void demangle(llvm::raw_ostream &OS, const char *Mangled) {
|
static void demangle(llvm::raw_ostream &OS, const std::string &Mangled) {
|
||||||
int Status;
|
int Status;
|
||||||
char *Demangled = itaniumDemangle(Mangled, nullptr, nullptr, &Status);
|
char *Demangled = nullptr;
|
||||||
|
if ((Mangled.size() >= 2 && Mangled.compare(0, 2, "_Z")) ||
|
||||||
|
(Mangled.size() >= 4 && Mangled.compare(0, 4, "___Z")))
|
||||||
|
Demangled = itaniumDemangle(Mangled.c_str(), nullptr, nullptr, &Status);
|
||||||
OS << (Demangled ? Demangled : Mangled) << '\n';
|
OS << (Demangled ? Demangled : Mangled) << '\n';
|
||||||
free(Demangled);
|
free(Demangled);
|
||||||
}
|
}
|
||||||
@ -24,7 +27,7 @@ static void demangle(llvm::raw_ostream &OS, const char *Mangled) {
|
|||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
for (std::string Mangled; std::getline(std::cin, Mangled);)
|
for (std::string Mangled; std::getline(std::cin, Mangled);)
|
||||||
demangle(llvm::outs(), Mangled.c_str());
|
demangle(llvm::outs(), Mangled);
|
||||||
else
|
else
|
||||||
for (int I = 1; I < argc; ++I)
|
for (int I = 1; I < argc; ++I)
|
||||||
demangle(llvm::outs(), argv[I]);
|
demangle(llvm::outs(), argv[I]);
|
||||||
|
@ -8,4 +8,4 @@
|
|||||||
|
|
||||||
#define CLANG_VENDOR "FreeBSD "
|
#define CLANG_VENDOR "FreeBSD "
|
||||||
|
|
||||||
#define SVN_REVISION "292732"
|
#define SVN_REVISION "292951"
|
||||||
|
@ -4,5 +4,5 @@
|
|||||||
#define LLD_VERSION_STRING "4.0.0"
|
#define LLD_VERSION_STRING "4.0.0"
|
||||||
#define LLD_VERSION_MAJOR 4
|
#define LLD_VERSION_MAJOR 4
|
||||||
#define LLD_VERSION_MINOR 0
|
#define LLD_VERSION_MINOR 0
|
||||||
#define LLD_REVISION_STRING "292732"
|
#define LLD_REVISION_STRING "292951"
|
||||||
#define LLD_REPOSITORY_STRING "FreeBSD"
|
#define LLD_REPOSITORY_STRING "FreeBSD"
|
||||||
|
Loading…
Reference in New Issue
Block a user