aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/DirectX
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/DirectX')
-rw-r--r--llvm/lib/Target/DirectX/DXILPrepare.cpp23
-rw-r--r--llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp36
-rw-r--r--llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp57
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);