DxilUtil.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilUtil.h //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // DXIL helper functions. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. #include <unordered_set>
  13. #include <string>
  14. #include <memory>
  15. #include "llvm/ADT/StringRef.h"
  16. #include "llvm/ADT/Twine.h"
  17. #include "llvm/IR/Constants.h"
  18. #include "dxc/DXIL/DxilConstants.h"
  19. #include "dxc/DXIL/DxilResourceProperties.h"
  20. namespace llvm {
  21. class Type;
  22. class GlobalVariable;
  23. class Function;
  24. class Module;
  25. class MemoryBuffer;
  26. class LLVMContext;
  27. class DiagnosticInfo;
  28. class Value;
  29. class Instruction;
  30. class CallInst;
  31. class BasicBlock;
  32. class raw_ostream;
  33. class ModulePass;
  34. class PassRegistry;
  35. class DebugInfoFinder;
  36. class DebugLoc;
  37. class DIGlobalVariable;
  38. class ConstantInt;
  39. class SwitchInst;
  40. ModulePass *createDxilLoadMetadataPass();
  41. void initializeDxilLoadMetadataPass(llvm::PassRegistry&);
  42. }
  43. namespace hlsl {
  44. class DxilFieldAnnotation;
  45. class DxilModule;
  46. class DxilTypeSystem;
  47. class OP;
  48. namespace dxilutil {
  49. extern const char ManglingPrefix[];
  50. extern const char EntryPrefix[];
  51. extern const char *kResourceMapErrorMsg;
  52. unsigned
  53. GetLegacyCBufferFieldElementSize(DxilFieldAnnotation &fieldAnnotation,
  54. llvm::Type *Ty, DxilTypeSystem &typeSys);
  55. llvm::Type *GetArrayEltTy(llvm::Type *Ty);
  56. bool HasDynamicIndexing(llvm::Value *V);
  57. // Find alloca insertion point, given instruction
  58. llvm::Instruction *FindAllocaInsertionPt(llvm::Instruction* I); // Considers entire parent function
  59. llvm::Instruction *FindAllocaInsertionPt(llvm::BasicBlock* BB); // Only considers provided block
  60. llvm::Instruction *FindAllocaInsertionPt(llvm::Function* F);
  61. llvm::Instruction *SkipAllocas(llvm::Instruction *I);
  62. // Get first non-alloca insertion point, to avoid inserting non-allocas before alloca
  63. llvm::Instruction *FirstNonAllocaInsertionPt(llvm::Instruction* I); // Considers entire parent function
  64. llvm::Instruction *FirstNonAllocaInsertionPt(llvm::BasicBlock* BB); // Only considers provided block
  65. llvm::Instruction *FirstNonAllocaInsertionPt(llvm::Function* F);
  66. bool IsStaticGlobal(llvm::GlobalVariable *GV);
  67. bool IsSharedMemoryGlobal(llvm::GlobalVariable *GV);
  68. bool RemoveUnusedFunctions(llvm::Module &M, llvm::Function *EntryFunc,
  69. llvm::Function *PatchConstantFunc, bool IsLib);
  70. llvm::DIGlobalVariable *FindGlobalVariableDebugInfo(llvm::GlobalVariable *GV,
  71. llvm::DebugInfoFinder &DbgInfoFinder);
  72. void EmitErrorOnInstruction(llvm::Instruction *I, llvm::Twine Msg);
  73. void EmitWarningOnInstruction(llvm::Instruction *I, llvm::Twine Msg);
  74. void EmitErrorOnFunction(llvm::LLVMContext &Ctx, llvm::Function *F, llvm::Twine Msg);
  75. void EmitWarningOnFunction(llvm::LLVMContext &Ctx, llvm::Function *F, llvm::Twine Msg);
  76. void EmitErrorOnGlobalVariable(llvm::LLVMContext &Ctx, llvm::GlobalVariable *GV, llvm::Twine Msg);
  77. void EmitWarningOnGlobalVariable(llvm::LLVMContext &Ctx, llvm::GlobalVariable *GV, llvm::Twine Msg);
  78. void EmitErrorOnContext(llvm::LLVMContext &Ctx, llvm::Twine Msg);
  79. void EmitWarningOnContext(llvm::LLVMContext &Ctx, llvm::Twine Msg);
  80. void EmitNoteOnContext(llvm::LLVMContext &Ctx, llvm::Twine Msg);
  81. void EmitResMappingError(llvm::Instruction *Res);
  82. // Simple demangle just support case "\01?name@" pattern.
  83. llvm::StringRef DemangleFunctionName(llvm::StringRef name);
  84. // ReplaceFunctionName replaces the undecorated portion of originalName with undecorated newName
  85. std::string ReplaceFunctionName(llvm::StringRef originalName, llvm::StringRef newName);
  86. void PrintEscapedString(llvm::StringRef Name, llvm::raw_ostream &Out);
  87. void PrintUnescapedString(llvm::StringRef Name, llvm::raw_ostream &Out);
  88. // Change select/phi on operands into select/phi on operation.
  89. // phi0 = phi a0, b0, c0
  90. // phi1 = phi a1, b1, c1
  91. // Inst = Add(phi0, phi1);
  92. // into
  93. // A = Add(a0, a1);
  94. // B = Add(b0, b1);
  95. // C = Add(c0, c1);
  96. // NewInst = phi A, B, C
  97. // Only support 1 operand now, other oerands should be Constant.
  98. llvm::Value * SelectOnOperation(llvm::Instruction *Inst, unsigned operandIdx);
  99. // Collect all select operand used by Inst.
  100. void CollectSelect(llvm::Instruction *Inst,
  101. std::unordered_set<llvm::Instruction *> &selectSet);
  102. // If all operands are the same for a select inst, replace it with the operand.
  103. // Returns replacement value if successful
  104. llvm::Value *MergeSelectOnSameValue(llvm::Instruction *SelInst,
  105. unsigned startOpIdx,
  106. unsigned numOperands);
  107. bool SimplifyTrivialPHIs(llvm::BasicBlock *BB);
  108. llvm::BasicBlock *GetSwitchSuccessorForCond(llvm::SwitchInst *Switch, llvm::ConstantInt *Cond);
  109. void MigrateDebugValue(llvm::Value *Old, llvm::Value *New);
  110. void TryScatterDebugValueToVectorElements(llvm::Value *Val);
  111. std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::StringRef BC,
  112. llvm::LLVMContext &Ctx, std::string &DiagStr);
  113. std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::MemoryBuffer *MB,
  114. llvm::LLVMContext &Ctx, std::string &DiagStr);
  115. std::unique_ptr<llvm::Module> LoadModuleFromBitcodeLazy(std::unique_ptr<llvm::MemoryBuffer> &&MB,
  116. llvm::LLVMContext &Ctx, std::string &DiagStr);
  117. void PrintDiagnosticHandler(const llvm::DiagnosticInfo &DI, void *Context);
  118. bool IsIntegerOrFloatingPointType(llvm::Type *Ty);
  119. // Returns true if type contains HLSL Object type (resource)
  120. bool ContainsHLSLObjectType(llvm::Type *Ty);
  121. std::pair<bool, DxilResourceProperties> GetHLSLResourceProperties(llvm::Type *Ty);
  122. bool IsHLSLResourceType(llvm::Type *Ty);
  123. bool IsHLSLObjectType(llvm::Type *Ty);
  124. bool IsHLSLRayQueryType(llvm::Type *Ty);
  125. bool IsHLSLResourceDescType(llvm::Type *Ty);
  126. bool IsResourceSingleComponent(llvm::Type *Ty);
  127. uint8_t GetResourceComponentCount(llvm::Type *Ty);
  128. bool IsSplat(llvm::ConstantDataVector *cdv);
  129. llvm::Type* StripArrayTypes(llvm::Type *Ty, llvm::SmallVectorImpl<unsigned> *OuterToInnerLengths = nullptr);
  130. llvm::Type* WrapInArrayTypes(llvm::Type *Ty, llvm::ArrayRef<unsigned> OuterToInnerLengths);
  131. llvm::CallInst *TranslateCallRawBufferLoadToBufferLoad(
  132. llvm::CallInst *CI, llvm::Function *newFunction, hlsl::OP *op);
  133. void ReplaceRawBufferLoadWithBufferLoad(llvm::Function *F, hlsl::OP *op);
  134. llvm::CallInst *TranslateCallRawBufferStoreToBufferStore(
  135. llvm::CallInst *CI, llvm::Function *newFunction, hlsl::OP *op);
  136. void ReplaceRawBufferStoreWithBufferStore(llvm::Function *F, hlsl::OP *op);
  137. void ReplaceRawBufferLoad64Bit(llvm::Function *F, llvm::Type *EltTy, hlsl::OP *hlslOP);
  138. void ReplaceRawBufferStore64Bit(llvm::Function *F, llvm::Type *ETy, hlsl::OP *hlslOP);
  139. bool IsConvergentMarker(llvm::Value *V);
  140. llvm::Value *GetConvergentSource(llvm::Value *V);
  141. }
  142. }