aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR')
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Function.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/IR/GCStrategy.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Globals.cpp37
-rw-r--r--contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp20
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Instructions.cpp13
-rw-r--r--contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp22
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Verifier.cpp110
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(),