From 804f034bd18789e9bbf4c70c10189dd6dbf04128 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Sat, 28 Sep 2013 00:22:27 +0000 Subject: [PATCH] AutoUpgrade: upgrade from scalar TBAA format to struct-path aware TBAA format. We treat TBAA tags as struct-path aware TBAA format when the first operand is a MDNode and the tag has 3 or more operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191593 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/AutoUpgrade.h | 5 +++++ lib/AsmParser/LLParser.cpp | 7 +++++++ lib/AsmParser/LLParser.h | 2 ++ lib/Bitcode/Reader/BitcodeReader.cpp | 6 ++++++ lib/Bitcode/Reader/BitcodeReader.h | 2 ++ lib/IR/AutoUpgrade.cpp | 27 +++++++++++++++++++++++++++ test/Bitcode/upgrade-tbaa.ll | 23 +++++++++++++++++++++++ 7 files changed, 72 insertions(+) create mode 100644 test/Bitcode/upgrade-tbaa.ll diff --git a/include/llvm/AutoUpgrade.h b/include/llvm/AutoUpgrade.h index ca3446e4555..8df87faf412 100644 --- a/include/llvm/AutoUpgrade.h +++ b/include/llvm/AutoUpgrade.h @@ -19,6 +19,7 @@ namespace llvm { class GlobalVariable; class Function; class CallInst; + class Instruction; /// This is a more granular function that simply checks an intrinsic function /// for upgrading, and returns true if it requires upgrading. It may return @@ -39,6 +40,10 @@ namespace llvm { /// This checks for global variables which should be upgraded. It returns true /// if it requires upgrading. bool UpgradeGlobalVariable(GlobalVariable *GV); + + /// If the TBAA tag for the given instruction uses the scalar TBAA format, + /// we upgrade it to the struct-path aware TBAA format. + void UpgradeInstWithTBAATag(Instruction *I); } // End llvm namespace #endif diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 336518c4017..2cf2de674e0 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/ValueSymbolTable.h" @@ -65,6 +66,9 @@ bool LLParser::ValidateEndOfModule() { ForwardRefInstMetadata.clear(); } + for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++) + UpgradeInstWithTBAATag(InstsWithTBAATag[I]); + // Handle any function attribute group forward references. for (std::map >::iterator I = ForwardRefAttrGroups.begin(), E = ForwardRefAttrGroups.end(); @@ -1427,6 +1431,9 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst, } } + if (MDK == LLVMContext::MD_tbaa) + InstsWithTBAATag.push_back(Inst); + // If this is the end of the list, we're done. } while (EatIfPresent(lltok::comma)); return false; diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 594281e9082..ded776c3989 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -107,6 +107,8 @@ namespace llvm { }; DenseMap > ForwardRefInstMetadata; + SmallVector InstsWithTBAATag; + // Type resolution handling data structures. The location is set when we // have processed a use of the type but not a definition yet. StringMap > NamedTypes; diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 0c20163c465..e408cd1f981 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -17,6 +17,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Operator.h" @@ -2123,6 +2124,8 @@ bool BitcodeReader::ParseMetadataAttachment() { return Error("Invalid metadata kind ID"); Value *Node = MDValueList.getValueFwdRef(Record[i+1]); Inst->setMetadata(I->second, cast(Node)); + if (I->second == LLVMContext::MD_tbaa) + InstsWithTBAATag.push_back(Inst); } break; } @@ -3134,6 +3137,9 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) { } std::vector >().swap(UpgradedIntrinsics); + for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++) + UpgradeInstWithTBAATag(InstsWithTBAATag[I]); + return false; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 9533597afa2..b284e8cac1e 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -144,6 +144,8 @@ class BitcodeReader : public GVMaterializer { std::vector > AliasInits; std::vector > FunctionPrefixes; + SmallVector InstsWithTBAATag; + /// MAttributes - The set of attributes by index. Index zero in the /// file is for null, and is thus not represented here. As such all indices /// are off by one. diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index a4f5289e5eb..9839b0674ea 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -391,3 +391,30 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { } } +void llvm::UpgradeInstWithTBAATag(Instruction *I) { + MDNode *MD = I->getMetadata(LLVMContext::MD_tbaa); + assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag"); + // Check if the tag uses struct-path aware TBAA format. + if (isa(MD->getOperand(0)) && MD->getNumOperands() >= 3) + return; + + if (MD->getNumOperands() == 3) { + Value *Elts[] = { + MD->getOperand(0), + MD->getOperand(1) + }; + MDNode *ScalarType = MDNode::get(I->getContext(), Elts); + // Create a MDNode + Value *Elts2[] = { + ScalarType, ScalarType, + Constant::getNullValue(Type::getInt64Ty(I->getContext())), + MD->getOperand(2) + }; + I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts2)); + } else { + // Create a MDNode + Value *Elts[] = {MD, MD, + Constant::getNullValue(Type::getInt64Ty(I->getContext()))}; + I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts)); + } +} diff --git a/test/Bitcode/upgrade-tbaa.ll b/test/Bitcode/upgrade-tbaa.ll new file mode 100644 index 00000000000..e7389095b8c --- /dev/null +++ b/test/Bitcode/upgrade-tbaa.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +; Function Attrs: nounwind +define void @_Z4testPiPf(i32* nocapture %pI, float* nocapture %pF) #0 { +entry: + store i32 0, i32* %pI, align 4, !tbaa !{metadata !"int", metadata !0} + ; CHECK: store i32 0, i32* %pI, align 4, !tbaa [[TAG_INT:!.*]] + store float 1.000000e+00, float* %pF, align 4, !tbaa !2 + ; CHECK: store float 1.000000e+00, float* %pF, align 4, !tbaa [[TAG_FLOAT:!.*]] + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!0 = metadata !{metadata !"omnipotent char", metadata !1} +!1 = metadata !{metadata !"Simple C/C++ TBAA"} +!2 = metadata !{metadata !"float", metadata !0} + +; CHECK: [[TAG_INT]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0} +; CHECK: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR:!.*]]} +; CHECK: [[TYPE_CHAR]] = metadata !{metadata !"omnipotent char", metadata !{{.*}} +; CHECK: [[TAG_FLOAT]] = metadata !{metadata [[TYPE_FLOAT:!.*]], metadata [[TYPE_FLOAT]], i64 0} +; CHECK: [[TYPE_FLOAT]] = metadata !{metadata !"float", metadata [[TYPE_CHAR]]}