diff options
author | Yevgeny Rouban <yevgeny.rouban@azul.com> | 2019-08-13 04:03:38 +0000 |
---|---|---|
committer | Yevgeny Rouban <yevgeny.rouban@azul.com> | 2019-08-13 04:03:38 +0000 |
commit | 8b996dc16ee4ed16922b33c616b3c21911438d5f (patch) | |
tree | d11adda41eda2298c7ea90585df8fb1c69ec988a /llvm/lib/IR/Verifier.cpp | |
parent | 3c7c053145fa98a017d426b475a9cf9c001c9da1 (diff) | |
download | bcm5719-llvm-8b996dc16ee4ed16922b33c616b3c21911438d5f.tar.gz bcm5719-llvm-8b996dc16ee4ed16922b33c616b3c21911438d5f.zip |
Verifier: check prof branch_weights
This patch is to check some of constraints on
!pro branch_weights metadata:
https://llvm.org/docs/BranchWeightMetadata.html
Reviewers: asbirlea, reames, chandlerc
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D61179
llvm-svn: 368647
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index f961aa73c9d..2e109c5f6d9 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -418,6 +418,7 @@ private: void visitBasicBlock(BasicBlock &BB); void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitDereferenceableMetadata(Instruction &I, MDNode *MD); + void visitProfMetadata(Instruction &I, MDNode *MD); template <class Ty> bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); @@ -3996,6 +3997,45 @@ void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) { "dereferenceable_or_null metadata value must be an i64!", &I); } +void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { + Assert(MD->getNumOperands() >= 2, + "!prof annotations should have no less than 2 operands", MD); + + // Check first operand. + Assert(MD->getOperand(0) != nullptr, "first operand should not be null", MD); + Assert(isa<MDString>(MD->getOperand(0)), + "expected string with name of the !prof annotation", MD); + MDString *MDS = cast<MDString>(MD->getOperand(0)); + StringRef ProfName = MDS->getString(); + + // Check consistency of !prof branch_weights metadata. + if (ProfName.equals("branch_weights")) { + unsigned ExpectedNumOperands = 0; + if (BranchInst *BI = dyn_cast<BranchInst>(&I)) + ExpectedNumOperands = BI->getNumSuccessors(); + else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I)) + ExpectedNumOperands = SI->getNumSuccessors(); + else if (isa<CallInst>(&I) || isa<InvokeInst>(&I)) + ExpectedNumOperands = 1; + else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I)) + ExpectedNumOperands = IBI->getNumDestinations(); + else if (isa<SelectInst>(&I)) + ExpectedNumOperands = 2; + else + CheckFailed("!prof branch_weights are not allowed for this instruction", + MD); + + Assert(MD->getNumOperands() == 1 + ExpectedNumOperands, + "Wrong number of operands", MD); + for (unsigned i = 1; i < MD->getNumOperands(); ++i) { + auto &MDO = MD->getOperand(i); + Assert(MDO, "second operand should not be null", MD); + Assert(mdconst::dyn_extract<ConstantInt>(MDO), + "!prof brunch_weights operand is not a const int"); + } + } +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { @@ -4153,6 +4193,9 @@ void Verifier::visitInstruction(Instruction &I) { "alignment is larger that implementation defined limit", &I); } + if (MDNode *MD = I.getMetadata(LLVMContext::MD_prof)) + visitProfMetadata(I, MD); + if (MDNode *N = I.getDebugLoc().getAsMDNode()) { AssertDI(isa<DILocation>(N), "invalid !dbg metadata attachment", &I, N); visitMDNode(*N); |