diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR')
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/Function.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/GCStrategy.cpp | 5 | ||||
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/Globals.cpp | 37 | ||||
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp | 20 | ||||
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/Instructions.cpp | 13 | ||||
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp | 22 | ||||
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/Verifier.cpp | 110 |
7 files changed, 151 insertions, 58 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/Function.cpp b/contrib/llvm-project/llvm/lib/IR/Function.cpp index 53df94366760..d4138133721e 100644 --- a/contrib/llvm-project/llvm/lib/IR/Function.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Function.cpp @@ -354,6 +354,8 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty, B.addAttribute("frame-pointer", "all"); break; } + if (M->getModuleFlag("function_return_thunk_extern")) + B.addAttribute(Attribute::FnRetThunkExtern); F->addFnAttrs(B); return F; } diff --git a/contrib/llvm-project/llvm/lib/IR/GCStrategy.cpp b/contrib/llvm-project/llvm/lib/IR/GCStrategy.cpp index f3bc5b74f8fd..5833dc26c57e 100644 --- a/contrib/llvm-project/llvm/lib/IR/GCStrategy.cpp +++ b/contrib/llvm-project/llvm/lib/IR/GCStrategy.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/GCStrategy.h" +#include "llvm/ADT/Twine.h" using namespace llvm; @@ -32,7 +33,7 @@ std::unique_ptr<GCStrategy> llvm::getGCStrategy(const StringRef Name) { const std::string error = std::string("unsupported GC: ") + Name.str() + " (did you remember to link and initialize the library?)"; - report_fatal_error(error); + report_fatal_error(Twine(error)); } else - report_fatal_error(std::string("unsupported GC: ") + Name.str()); + report_fatal_error(Twine(std::string("unsupported GC: ") + Name.str())); } diff --git a/contrib/llvm-project/llvm/lib/IR/Globals.cpp b/contrib/llvm-project/llvm/lib/IR/Globals.cpp index 3265050261c8..51a22897babd 100644 --- a/contrib/llvm-project/llvm/lib/IR/Globals.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Globals.cpp @@ -316,32 +316,38 @@ bool GlobalObject::canIncreaseAlignment() const { return true; } +template <typename Operation> static const GlobalObject * -findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) { - if (auto *GO = dyn_cast<GlobalObject>(C)) +findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases, + const Operation &Op) { + if (auto *GO = dyn_cast<GlobalObject>(C)) { + Op(*GO); return GO; - if (auto *GA = dyn_cast<GlobalAlias>(C)) + } + if (auto *GA = dyn_cast<GlobalAlias>(C)) { + Op(*GA); if (Aliases.insert(GA).second) - return findBaseObject(GA->getOperand(0), Aliases); + return findBaseObject(GA->getOperand(0), Aliases, Op); + } if (auto *CE = dyn_cast<ConstantExpr>(C)) { switch (CE->getOpcode()) { case Instruction::Add: { - auto *LHS = findBaseObject(CE->getOperand(0), Aliases); - auto *RHS = findBaseObject(CE->getOperand(1), Aliases); + auto *LHS = findBaseObject(CE->getOperand(0), Aliases, Op); + auto *RHS = findBaseObject(CE->getOperand(1), Aliases, Op); if (LHS && RHS) return nullptr; return LHS ? LHS : RHS; } case Instruction::Sub: { - if (findBaseObject(CE->getOperand(1), Aliases)) + if (findBaseObject(CE->getOperand(1), Aliases, Op)) return nullptr; - return findBaseObject(CE->getOperand(0), Aliases); + return findBaseObject(CE->getOperand(0), Aliases, Op); } case Instruction::IntToPtr: case Instruction::PtrToInt: case Instruction::BitCast: case Instruction::GetElementPtr: - return findBaseObject(CE->getOperand(0), Aliases); + return findBaseObject(CE->getOperand(0), Aliases, Op); default: break; } @@ -351,7 +357,7 @@ findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) { const GlobalObject *GlobalValue::getAliaseeObject() const { DenseSet<const GlobalAlias *> Aliases; - return findBaseObject(this, Aliases); + return findBaseObject(this, Aliases, [](const GlobalValue &) {}); } bool GlobalValue::isAbsoluteSymbolRef() const { @@ -544,7 +550,7 @@ void GlobalAlias::setAliasee(Constant *Aliasee) { const GlobalObject *GlobalAlias::getAliaseeObject() const { DenseSet<const GlobalAlias *> Aliases; - return findBaseObject(getOperand(0), Aliases); + return findBaseObject(getOperand(0), Aliases, [](const GlobalValue &) {}); } //===----------------------------------------------------------------------===// @@ -577,5 +583,12 @@ void GlobalIFunc::eraseFromParent() { const Function *GlobalIFunc::getResolverFunction() const { DenseSet<const GlobalAlias *> Aliases; - return dyn_cast<Function>(findBaseObject(getResolver(), Aliases)); + return dyn_cast<Function>( + findBaseObject(getResolver(), Aliases, [](const GlobalValue &) {})); +} + +void GlobalIFunc::applyAlongResolverPath( + function_ref<void(const GlobalValue &)> Op) const { + DenseSet<const GlobalAlias *> Aliases; + findBaseObject(getResolver(), Aliases, Op); } diff --git a/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp b/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp index c75b1aa7c1d6..088fcfdec742 100644 --- a/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp +++ b/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp @@ -93,6 +93,9 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, } else if (*I == '=') { ++I; Type = isOutput; + } else if (*I == '!') { + ++I; + Type = isLabel; } if (*I == '*') { @@ -265,14 +268,14 @@ Error InlineAsm::verify(FunctionType *Ty, StringRef ConstStr) { return makeStringError("failed to parse constraints"); unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; - unsigned NumIndirect = 0; + unsigned NumIndirect = 0, NumLabels = 0; for (const ConstraintInfo &Constraint : Constraints) { switch (Constraint.Type) { case InlineAsm::isOutput: - if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0) - return makeStringError("output constraint occurs after input " - "or clobber constraint"); + if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0 || NumLabels != 0) + return makeStringError("output constraint occurs after input, " + "clobber or label constraint"); if (!Constraint.isIndirect) { ++NumOutputs; @@ -289,6 +292,13 @@ Error InlineAsm::verify(FunctionType *Ty, StringRef ConstStr) { case InlineAsm::isClobber: ++NumClobbers; break; + case InlineAsm::isLabel: + if (NumClobbers) + return makeStringError("label constraint occurs after clobber " + "constraint"); + + ++NumLabels; + break; } } @@ -312,5 +322,7 @@ Error InlineAsm::verify(FunctionType *Ty, StringRef ConstStr) { if (Ty->getNumParams() != NumInputs) return makeStringError("number of input constraints does not match number " "of parameters"); + + // We don't have access to labels here, NumLabels will be checked separately. return Error::success(); } diff --git a/contrib/llvm-project/llvm/lib/IR/Instructions.cpp b/contrib/llvm-project/llvm/lib/IR/Instructions.cpp index b333f40f3ce9..26171f537244 100644 --- a/contrib/llvm-project/llvm/lib/IR/Instructions.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Instructions.cpp @@ -960,15 +960,10 @@ void CallBrInst::init(FunctionType *FTy, Value *Fn, BasicBlock *Fallthrough, setName(NameStr); } -void CallBrInst::updateArgBlockAddresses(unsigned i, BasicBlock *B) { - assert(getNumIndirectDests() > i && "IndirectDest # out of range for callbr"); - if (BasicBlock *OldBB = getIndirectDest(i)) { - BlockAddress *Old = BlockAddress::get(OldBB); - BlockAddress *New = BlockAddress::get(B); - for (unsigned ArgNo = 0, e = arg_size(); ArgNo != e; ++ArgNo) - if (dyn_cast<BlockAddress>(getArgOperand(ArgNo)) == Old) - setArgOperand(ArgNo, New); - } +BlockAddress * +CallBrInst::getBlockAddressForIndirectDest(unsigned DestNo) const { + return BlockAddress::get(const_cast<Function *>(getFunction()), + getIndirectDest(DestNo)); } CallBrInst::CallBrInst(const CallBrInst &CBI) diff --git a/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp b/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp index 65a9a32ad2c5..c50d6901c9da 100644 --- a/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp +++ b/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp @@ -694,8 +694,10 @@ unsigned BinaryOpIntrinsic::getNoWrapKind() const { return OverflowingBinaryOperator::NoUnsignedWrap; } -const GCStatepointInst *GCProjectionInst::getStatepoint() const { +const Value *GCProjectionInst::getStatepoint() const { const Value *Token = getArgOperand(0); + if (isa<UndefValue>(Token)) + return Token; // This takes care both of relocates for call statepoints and relocates // on normal path of invoke statepoint. @@ -714,13 +716,23 @@ const GCStatepointInst *GCProjectionInst::getStatepoint() const { } Value *GCRelocateInst::getBasePtr() const { - if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) + auto Statepoint = getStatepoint(); + if (isa<UndefValue>(Statepoint)) + return UndefValue::get(Statepoint->getType()); + + auto *GCInst = cast<GCStatepointInst>(Statepoint); + if (auto Opt = GCInst->getOperandBundle(LLVMContext::OB_gc_live)) return *(Opt->Inputs.begin() + getBasePtrIndex()); - return *(getStatepoint()->arg_begin() + getBasePtrIndex()); + return *(GCInst->arg_begin() + getBasePtrIndex()); } Value *GCRelocateInst::getDerivedPtr() const { - if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) + auto *Statepoint = getStatepoint(); + if (isa<UndefValue>(Statepoint)) + return UndefValue::get(Statepoint->getType()); + + auto *GCInst = cast<GCStatepointInst>(Statepoint); + if (auto Opt = GCInst->getOperandBundle(LLVMContext::OB_gc_live)) return *(Opt->Inputs.begin() + getDerivedPtrIndex()); - return *(getStatepoint()->arg_begin() + getDerivedPtrIndex()); + return *(GCInst->arg_begin() + getDerivedPtrIndex()); } diff --git a/contrib/llvm-project/llvm/lib/IR/Verifier.cpp b/contrib/llvm-project/llvm/lib/IR/Verifier.cpp index 75d02f4c8c82..e3ea256af16d 100644 --- a/contrib/llvm-project/llvm/lib/IR/Verifier.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Verifier.cpp @@ -469,6 +469,9 @@ private: void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitDereferenceableMetadata(Instruction &I, MDNode *MD); void visitProfMetadata(Instruction &I, MDNode *MD); + void visitCallStackMetadata(MDNode *MD); + void visitMemProfMetadata(Instruction &I, MDNode *MD); + void visitCallsiteMetadata(Instruction &I, MDNode *MD); void visitAnnotationMetadata(MDNode *Annotation); void visitAliasScopeMetadata(const MDNode *MD); void visitAliasScopeListMetadata(const MDNode *MD); @@ -1624,8 +1627,10 @@ Verifier::visitModuleFlag(const MDNode *Op, break; case Module::Min: { - Check(mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2)), - "invalid value for 'min' module flag (expected constant integer)", + auto *V = mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2)); + Check(V && V->getValue().isNonNegative(), + "invalid value for 'min' module flag (expected constant non-negative " + "integer)", Op->getOperand(2)); break; } @@ -2200,7 +2205,13 @@ bool Verifier::verifyAttributeCount(AttributeList Attrs, unsigned Params) { void Verifier::verifyInlineAsmCall(const CallBase &Call) { const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand()); unsigned ArgNo = 0; + unsigned LabelNo = 0; for (const InlineAsm::ConstraintInfo &CI : IA->ParseConstraints()) { + if (CI.Type == InlineAsm::isLabel) { + ++LabelNo; + continue; + } + // Only deal with constraints that correspond to call arguments. if (!CI.hasArg()) continue; @@ -2222,6 +2233,15 @@ void Verifier::verifyInlineAsmCall(const CallBase &Call) { ArgNo++; } + + if (auto *CallBr = dyn_cast<CallBrInst>(&Call)) { + Check(LabelNo == CallBr->getNumIndirectDests(), + "Number of label constraints does not match number of callbr dests", + &Call); + } else { + Check(LabelNo == 0, "Label constraints can only be used with callbr", + &Call); + } } /// Verify that statepoint intrinsic is well formed. @@ -2839,25 +2859,6 @@ void Verifier::visitCallBrInst(CallBrInst &CBI) { Check(CBI.isInlineAsm(), "Callbr is currently only used for asm-goto!", &CBI); const InlineAsm *IA = cast<InlineAsm>(CBI.getCalledOperand()); Check(!IA->canThrow(), "Unwinding from Callbr is not allowed"); - for (unsigned i = 0, e = CBI.getNumSuccessors(); i != e; ++i) - Check(CBI.getSuccessor(i)->getType()->isLabelTy(), - "Callbr successors must all have pointer type!", &CBI); - for (unsigned i = 0, e = CBI.getNumOperands(); i != e; ++i) { - Check(i >= CBI.arg_size() || !isa<BasicBlock>(CBI.getOperand(i)), - "Using an unescaped label as a callbr argument!", &CBI); - if (isa<BasicBlock>(CBI.getOperand(i))) - for (unsigned j = i + 1; j != e; ++j) - Check(CBI.getOperand(i) != CBI.getOperand(j), - "Duplicate callbr destination!", &CBI); - } - { - SmallPtrSet<BasicBlock *, 4> ArgBBs; - for (Value *V : CBI.args()) - if (auto *BA = dyn_cast<BlockAddress>(V)) - ArgBBs.insert(BA->getBasicBlock()); - for (BasicBlock *BB : CBI.getIndirectDests()) - Check(ArgBBs.count(BB), "Indirect label missing from arglist.", &CBI); - } verifyInlineAsmCall(CBI); visitTerminator(CBI); @@ -4489,6 +4490,55 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { } } +void Verifier::visitCallStackMetadata(MDNode *MD) { + // Call stack metadata should consist of a list of at least 1 constant int + // (representing a hash of the location). + Check(MD->getNumOperands() >= 1, + "call stack metadata should have at least 1 operand", MD); + + for (const auto &Op : MD->operands()) + Check(mdconst::dyn_extract_or_null<ConstantInt>(Op), + "call stack metadata operand should be constant integer", Op); +} + +void Verifier::visitMemProfMetadata(Instruction &I, MDNode *MD) { + Check(isa<CallBase>(I), "!memprof metadata should only exist on calls", &I); + Check(MD->getNumOperands() >= 1, + "!memprof annotations should have at least 1 metadata operand " + "(MemInfoBlock)", + MD); + + // Check each MIB + for (auto &MIBOp : MD->operands()) { + MDNode *MIB = dyn_cast<MDNode>(MIBOp); + // The first operand of an MIB should be the call stack metadata. + // There rest of the operands should be MDString tags, and there should be + // at least one. + Check(MIB->getNumOperands() >= 2, + "Each !memprof MemInfoBlock should have at least 2 operands", MIB); + + // Check call stack metadata (first operand). + Check(MIB->getOperand(0) != nullptr, + "!memprof MemInfoBlock first operand should not be null", MIB); + Check(isa<MDNode>(MIB->getOperand(0)), + "!memprof MemInfoBlock first operand should be an MDNode", MIB); + MDNode *StackMD = dyn_cast<MDNode>(MIB->getOperand(0)); + visitCallStackMetadata(StackMD); + + // Check that remaining operands are MDString. + Check(std::all_of(MIB->op_begin() + 1, MIB->op_end(), + [](const MDOperand &Op) { return isa<MDString>(Op); }), + "Not all !memprof MemInfoBlock operands 1 to N are MDString", MIB); + } +} + +void Verifier::visitCallsiteMetadata(Instruction &I, MDNode *MD) { + Check(isa<CallBase>(I), "!callsite metadata should only exist on calls", &I); + // Verify the partial callstack annotated from memprof profiles. This callsite + // is a part of a profiled allocation callstack. + visitCallStackMetadata(MD); +} + void Verifier::visitAnnotationMetadata(MDNode *Annotation) { Check(isa<MDTuple>(Annotation), "annotation must be a tuple"); Check(Annotation->getNumOperands() >= 1, @@ -4735,6 +4785,12 @@ void Verifier::visitInstruction(Instruction &I) { if (MDNode *MD = I.getMetadata(LLVMContext::MD_prof)) visitProfMetadata(I, MD); + if (MDNode *MD = I.getMetadata(LLVMContext::MD_memprof)) + visitMemProfMetadata(I, MD); + + if (MDNode *MD = I.getMetadata(LLVMContext::MD_callsite)) + visitCallsiteMetadata(I, MD); + if (MDNode *Annotation = I.getMetadata(LLVMContext::MD_annotation)) visitAnnotationMetadata(Annotation); @@ -5160,14 +5216,13 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { // In all other cases relocate should be tied to the statepoint directly. // This covers relocates on a normal return path of invoke statepoint and // relocates of a call statepoint. - auto Token = Call.getArgOperand(0); - Check(isa<GCStatepointInst>(Token), + auto *Token = Call.getArgOperand(0); + Check(isa<GCStatepointInst>(Token) || isa<UndefValue>(Token), "gc relocate is incorrectly tied to the statepoint", Call, Token); } // Verify rest of the relocate arguments. - const CallBase &StatepointCall = - *cast<GCRelocateInst>(Call).getStatepoint(); + const Value &StatepointCall = *cast<GCRelocateInst>(Call).getStatepoint(); // Both the base and derived must be piped through the safepoint. Value *Base = Call.getArgOperand(1); @@ -5182,7 +5237,10 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { const uint64_t DerivedIndex = cast<ConstantInt>(Derived)->getZExtValue(); // Check the bounds - if (auto Opt = StatepointCall.getOperandBundle(LLVMContext::OB_gc_live)) { + if (isa<UndefValue>(StatepointCall)) + break; + if (auto Opt = cast<GCStatepointInst>(StatepointCall) + .getOperandBundle(LLVMContext::OB_gc_live)) { Check(BaseIndex < Opt->Inputs.size(), "gc.relocate: statepoint base index out of bounds", Call); Check(DerivedIndex < Opt->Inputs.size(), |