diff options
Diffstat (limited to 'llvm/lib/Target/DirectX')
-rw-r--r-- | llvm/lib/Target/DirectX/DXILPrepare.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp | 36 | ||||
-rw-r--r-- | llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp | 57 |
3 files changed, 61 insertions, 55 deletions
diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp index 703a9e5..c8866bf 100644 --- a/llvm/lib/Target/DirectX/DXILPrepare.cpp +++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp @@ -24,7 +24,6 @@ #include "llvm/IR/AttributeMask.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" -#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" @@ -240,11 +239,6 @@ public: for (size_t Idx = 0, End = F.arg_size(); Idx < End; ++Idx) F.removeParamAttrs(Idx, AttrMask); - // Lifetime intrinsics in LLVM 3.7 do not have the memory FnAttr - if (Intrinsic::ID IID = F.getIntrinsicID(); - IID == Intrinsic::lifetime_start || IID == Intrinsic::lifetime_end) - F.removeFnAttr(Attribute::Memory); - for (auto &BB : F) { IRBuilder<> Builder(&BB); for (auto &I : make_early_inc_range(BB)) { @@ -253,7 +247,7 @@ public: // Emtting NoOp bitcast instructions allows the ValueEnumerator to be // unmodified as it reserves instruction IDs during contruction. - if (auto *LI = dyn_cast<LoadInst>(&I)) { + if (auto LI = dyn_cast<LoadInst>(&I)) { if (Value *NoOpBitcast = maybeGenerateBitcast( Builder, PointerTypes, I, LI->getPointerOperand(), LI->getType())) { @@ -263,7 +257,7 @@ public: } continue; } - if (auto *SI = dyn_cast<StoreInst>(&I)) { + if (auto SI = dyn_cast<StoreInst>(&I)) { if (Value *NoOpBitcast = maybeGenerateBitcast( Builder, PointerTypes, I, SI->getPointerOperand(), SI->getValueOperand()->getType())) { @@ -274,7 +268,7 @@ public: } continue; } - if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) { + if (auto GEP = dyn_cast<GetElementPtrInst>(&I)) { if (Value *NoOpBitcast = maybeGenerateBitcast( Builder, PointerTypes, I, GEP->getPointerOperand(), GEP->getSourceElementType())) @@ -286,17 +280,6 @@ public: CB->removeRetAttrs(AttrMask); for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx) CB->removeParamAttrs(Idx, AttrMask); - // LLVM 3.7 Lifetime intrinics require an i8* pointer operand, so we - // insert a bitcast here to ensure that is the case - if (isa<LifetimeIntrinsic>(CB)) { - Value *PtrOperand = CB->getArgOperand(1); - Builder.SetInsertPoint(CB); - PointerType *PtrTy = cast<PointerType>(PtrOperand->getType()); - Value *NoOpBitcast = Builder.Insert( - CastInst::Create(Instruction::BitCast, PtrOperand, - Builder.getPtrTy(PtrTy->getAddressSpace()))); - CB->setArgOperand(1, NoOpBitcast); - } continue; } } diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp index 46d5d71..1d79c30 100644 --- a/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp +++ b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp @@ -2545,25 +2545,6 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID, Vals.clear(); } -// HLSL Change -namespace { -struct ValueNameCreator { - MallocAllocator Allocator; - SmallVector<ValueName *, 2> - ValueNames; // SmallVector N = 2 because we currently only expect this - // to hold ValueNames for Lifetime intrinsics - ~ValueNameCreator() { - for (auto *VN : ValueNames) - VN->Destroy(Allocator); - } - ValueName *create(StringRef Name, Value *V) { - ValueName *VN = ValueName::create(Name, Allocator, V); - ValueNames.push_back(VN); - return VN; - } -}; -} // anonymous namespace - // Emit names for globals/functions etc. void DXILBitcodeWriter::writeFunctionLevelValueSymbolTable( const ValueSymbolTable &VST) { @@ -2578,24 +2559,9 @@ void DXILBitcodeWriter::writeFunctionLevelValueSymbolTable( // to ensure the binary is the same no matter what values ever existed. SmallVector<const ValueName *, 16> SortedTable; - // HLSL Change - ValueNameCreator VNC; for (auto &VI : VST) { - ValueName *VN = VI.second->getValueName(); - // Clang mangles lifetime intrinsic names by appending '.p0' to the end, - // making them invalid lifetime intrinsics in LLVM 3.7. We can't - // demangle in dxil-prepare because it would result in invalid IR. - // Therefore we have to do this in the bitcode writer while writing its - // name to the symbol table. - if (const Function *Fn = dyn_cast<Function>(VI.getValue()); - Fn && Fn->isIntrinsic()) { - Intrinsic::ID IID = Fn->getIntrinsicID(); - if (IID == Intrinsic::lifetime_start || IID == Intrinsic::lifetime_end) - VN = VNC.create(Intrinsic::getBaseName(IID), VI.second); - } - SortedTable.push_back(VN); + SortedTable.push_back(VI.second->getValueName()); } - // The keys are unique, so there shouldn't be stability issues. llvm::sort(SortedTable, [](const ValueName *A, const ValueName *B) { return A->first() < B->first(); diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp index dfc79039c..1bd5dd7 100644 --- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp +++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp @@ -17,6 +17,7 @@ #include "llvm/Analysis/ModuleSummaryAnalysis.h" #include "llvm/IR/Constants.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/InitializePasses.h" @@ -52,6 +53,53 @@ public: } }; +static void legalizeLifetimeIntrinsics(Module &M) { + for (Function &F : M) { + Intrinsic::ID IID = F.getIntrinsicID(); + if (IID != Intrinsic::lifetime_start && IID != Intrinsic::lifetime_end) + continue; + + // Lifetime intrinsics in LLVM 3.7 do not have the memory FnAttr + F.removeFnAttr(Attribute::Memory); + + // Lifetime intrinsics in LLVM 3.7 do not have mangled names + F.setName(Intrinsic::getBaseName(IID)); + + // LLVM 3.7 Lifetime intrinics require an i8* operand, so we insert bitcasts + // to ensure that is the case + for (auto *User : make_early_inc_range(F.users())) { + CallInst *CI = dyn_cast<CallInst>(User); + assert(CI && "Expected user of a lifetime intrinsic function to be a " + "lifetime intrinsic call"); + Value *PtrOperand = CI->getArgOperand(1); + PointerType *PtrTy = cast<PointerType>(PtrOperand->getType()); + Value *NoOpBitCast = CastInst::Create(Instruction::BitCast, PtrOperand, + PtrTy, "", CI->getIterator()); + CI->setArgOperand(1, NoOpBitCast); + } + } +} + +static void removeLifetimeIntrinsics(Module &M) { + for (Function &F : make_early_inc_range(M)) { + if (Intrinsic::ID IID = F.getIntrinsicID(); + IID != Intrinsic::lifetime_start && IID != Intrinsic::lifetime_end) + continue; + + for (User *U : make_early_inc_range(F.users())) { + LifetimeIntrinsic *LI = dyn_cast<LifetimeIntrinsic>(U); + assert(LI && "Expected user of lifetime intrinsic function to be " + "a LifetimeIntrinsic instruction"); + BitCastInst *BCI = dyn_cast<BitCastInst>(LI->getArgOperand(1)); + assert(BCI && "Expected pointer operand of LifetimeIntrinsic to be a " + "BitCastInst"); + LI->eraseFromParent(); + BCI->eraseFromParent(); + } + F.eraseFromParent(); + } +} + class EmbedDXILPass : public llvm::ModulePass { public: static char ID; // Pass identification, replacement for typeid @@ -70,8 +118,17 @@ public: // Only the output bitcode need to be DXIL triple. M.setTargetTriple(Triple("dxil-ms-dx")); + // Perform late legalization of lifetime intrinsics that would otherwise + // fail the Module Verifier if performed in an earlier pass + legalizeLifetimeIntrinsics(M); + WriteDXILToFile(M, OS); + // We no longer need lifetime intrinsics after bitcode serialization, so we + // simply remove them to keep the Module Verifier happy after our + // not-so-legal legalizations + removeLifetimeIntrinsics(M); + // Recover triple. M.setTargetTriple(OriginalTriple); |