LLVM  16.0.0git
DXILPrepare.cpp
Go to the documentation of this file.
1 //===- DXILPrepare.cpp - Prepare LLVM Module for DXIL encoding ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file This file contains pases and utilities to convert a modern LLVM
10 /// module into a module compatible with the LLVM 3.7-based DirectX Intermediate
11 /// Language (DXIL).
12 //===----------------------------------------------------------------------===//
13 
14 #include "DirectX.h"
15 #include "PointerTypeAnalysis.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/IR/Instruction.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/InitializePasses.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Support/Compiler.h"
25 
26 #define DEBUG_TYPE "dxil-prepare"
27 
28 using namespace llvm;
29 using namespace llvm::dxil;
30 
31 namespace {
32 
33 constexpr bool isValidForDXIL(Attribute::AttrKind Attr) {
34  return is_contained({Attribute::Alignment,
35  Attribute::AlwaysInline,
36  Attribute::Builtin,
37  Attribute::ByVal,
38  Attribute::InAlloca,
41  Attribute::InlineHint,
42  Attribute::InReg,
44  Attribute::MinSize,
45  Attribute::Naked,
46  Attribute::Nest,
47  Attribute::NoAlias,
48  Attribute::NoBuiltin,
49  Attribute::NoCapture,
50  Attribute::NoDuplicate,
51  Attribute::NoImplicitFloat,
52  Attribute::NoInline,
53  Attribute::NonLazyBind,
54  Attribute::NonNull,
55  Attribute::Dereferenceable,
56  Attribute::DereferenceableOrNull,
57  Attribute::NoRedZone,
58  Attribute::NoReturn,
59  Attribute::NoUnwind,
60  Attribute::OptimizeForSize,
61  Attribute::OptimizeNone,
62  Attribute::ReadNone,
63  Attribute::ReadOnly,
64  Attribute::ArgMemOnly,
65  Attribute::Returned,
66  Attribute::ReturnsTwice,
67  Attribute::SExt,
68  Attribute::StackAlignment,
69  Attribute::StackProtect,
70  Attribute::StackProtectReq,
71  Attribute::StackProtectStrong,
72  Attribute::SafeStack,
73  Attribute::StructRet,
74  Attribute::SanitizeAddress,
75  Attribute::SanitizeThread,
76  Attribute::SanitizeMemory,
77  Attribute::UWTable,
78  Attribute::ZExt},
79  Attr);
80 }
81 
82 class DXILPrepareModule : public ModulePass {
83 
84  static Value *maybeGenerateBitcast(IRBuilder<> &Builder,
85  PointerTypeMap &PointerTypes,
86  Instruction &Inst, Value *Operand,
87  Type *Ty) {
88  // Omit bitcasts if the incoming value matches the instruction type.
89  auto It = PointerTypes.find(Operand);
90  if (It != PointerTypes.end())
91  if (cast<TypedPointerType>(It->second)->getElementType() == Ty)
92  return nullptr;
93  // Insert bitcasts where we are removing the instruction.
94  Builder.SetInsertPoint(&Inst);
95  // This code only gets hit in opaque-pointer mode, so the type of the
96  // pointer doesn't matter.
97  PointerType *PtrTy = cast<PointerType>(Operand->getType());
98  return Builder.Insert(
99  CastInst::Create(Instruction::BitCast, Operand,
100  Builder.getInt8PtrTy(PtrTy->getAddressSpace())));
101  }
102 
103 public:
104  bool runOnModule(Module &M) override {
105  PointerTypeMap PointerTypes = PointerTypeAnalysis::run(M);
106  AttributeMask AttrMask;
108  I = Attribute::AttrKind(I + 1)) {
109  if (!isValidForDXIL(I))
110  AttrMask.addAttribute(I);
111  }
112  for (auto &F : M.functions()) {
113  F.removeFnAttrs(AttrMask);
114  F.removeRetAttrs(AttrMask);
115  for (size_t Idx = 0, End = F.arg_size(); Idx < End; ++Idx)
116  F.removeParamAttrs(Idx, AttrMask);
117 
118  for (auto &BB : F) {
120  for (auto &I : make_early_inc_range(BB)) {
121  if (I.getOpcode() == Instruction::FNeg) {
122  Builder.SetInsertPoint(&I);
123  Value *In = I.getOperand(0);
124  Value *Zero = ConstantFP::get(In->getType(), -0.0);
125  I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
126  I.eraseFromParent();
127  continue;
128  }
129  // Only insert bitcasts if the IR is using opaque pointers.
130  if (M.getContext().supportsTypedPointers())
131  continue;
132 
133  // Emtting NoOp bitcast instructions allows the ValueEnumerator to be
134  // unmodified as it reserves instruction IDs during contruction.
135  if (auto LI = dyn_cast<LoadInst>(&I)) {
136  if (Value *NoOpBitcast = maybeGenerateBitcast(
137  Builder, PointerTypes, I, LI->getPointerOperand(),
138  LI->getType())) {
139  LI->replaceAllUsesWith(
140  Builder.CreateLoad(LI->getType(), NoOpBitcast));
141  LI->eraseFromParent();
142  }
143  continue;
144  }
145  if (auto SI = dyn_cast<StoreInst>(&I)) {
146  if (Value *NoOpBitcast = maybeGenerateBitcast(
147  Builder, PointerTypes, I, SI->getPointerOperand(),
148  SI->getValueOperand()->getType())) {
149 
150  SI->replaceAllUsesWith(
151  Builder.CreateStore(SI->getValueOperand(), NoOpBitcast));
152  SI->eraseFromParent();
153  }
154  continue;
155  }
156  if (auto GEP = dyn_cast<GetElementPtrInst>(&I)) {
157  if (Value *NoOpBitcast = maybeGenerateBitcast(
158  Builder, PointerTypes, I, GEP->getPointerOperand(),
159  GEP->getResultElementType()))
160  GEP->setOperand(0, NoOpBitcast);
161  continue;
162  }
163  if (auto *CB = dyn_cast<CallBase>(&I)) {
164  CB->removeFnAttrs(AttrMask);
165  CB->removeRetAttrs(AttrMask);
166  for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx)
167  CB->removeParamAttrs(Idx, AttrMask);
168  continue;
169  }
170  }
171  }
172  }
173  return true;
174  }
175 
176  DXILPrepareModule() : ModulePass(ID) {}
177 
178  static char ID; // Pass identification.
179 };
180 char DXILPrepareModule::ID = 0;
181 
182 } // end anonymous namespace
183 
184 INITIALIZE_PASS_BEGIN(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module",
185  false, false)
186 INITIALIZE_PASS_END(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module", false,
187  false)
188 
190  return new DXILPrepareModule();
191 }
llvm::Attribute::EndAttrKinds
@ EndAttrKinds
Sentinal value useful for loops.
Definition: Attributes.h:89
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
Pass.h
llvm::IRBuilder<>
llvm::CastInst::Create
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Definition: Instructions.cpp:3250
llvm::PointerType::getAddressSpace
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:682
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::AttributeMask
Definition: Attributes.h:969
llvm::MCID::Convergent
@ Convergent
Definition: MCInstrDesc.h:184
STLExtras.h
F
#define F(x, y, z)
Definition: MD5.cpp:55
PointerTypeAnalysis.h
Instruction.h
DEBUG_TYPE
#define DEBUG_TYPE
Definition: DXILPrepare.cpp:26
DirectX.h
false
Definition: StackSlotColoring.cpp:141
llvm::Instruction
Definition: Instruction.h:42
llvm::CallingConv::Cold
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
Definition: CallingConv.h:47
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::dxil::PointerTypeAnalysis::run
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Definition: PointerTypeAnalysis.cpp:189
Passes.h
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::dxil
Definition: DXILOperationCommon.h:23
llvm::Attribute::None
@ None
No attributes have been set.
Definition: Attributes.h:86
llvm::DenseMap< const Value *, Type * >
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::Attribute::AttrKind
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:84
llvm::make_early_inc_range
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:596
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:632
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1673
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
IRBuilder.h
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
Compiler.h
llvm::createDXILPrepareModulePass
ModulePass * createDXILPrepareModulePass()
Pass to convert modules into DXIL-compatable modules.
Definition: DXILPrepare.cpp:189
llvm::DenseMapBase::end
iterator end()
Definition: DenseMap.h:84
JumpTable
MIPS Relocation Principles In there are several elements of the llvm::ISD::NodeType enum that deal with addresses and or relocations These are defined in include llvm Target TargetSelectionDAG td JumpTable
Definition: Relocation.txt:6
llvm::ConstantFP::get
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
Definition: Constants.cpp:926
SmallVector.h
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module", false, false) INITIALIZE_PASS_END(DXILPrepareModule
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:171
llvm::AttributeMask::addAttribute
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
Definition: Attributes.h:984
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38