浏览代码

Add helper functions for working with precise (#323)

- Get/Set precise on in instruction in DxilMDHelper
    - Get precise based on instruction/global flags in DxilModule
David Peixotto 8 年之前
父节点
当前提交
16a3f0a881

+ 3 - 0
include/dxc/HLSL/DxilMetadataHelper.h

@@ -20,6 +20,7 @@ namespace llvm {
 class LLVMContext;
 class Module;
 class Function;
+class Instruction;
 class Value;
 class MDOperand;
 class Metadata;
@@ -378,6 +379,8 @@ public:
   static llvm::Value *ValueMDToValue(const llvm::MDOperand &MDO);
   llvm::MDTuple *Uint32VectorToConstMDTuple(const std::vector<unsigned> &Vec);
   void ConstMDTupleToUint32Vector(llvm::MDTuple *pTupleMD, std::vector<unsigned> &Vec);
+  static bool IsMarkedPrecise(llvm::Instruction *inst);
+  static void MarkPrecise(llvm::Instruction *inst);
 
 private:
   llvm::LLVMContext &m_Ctx;

+ 5 - 0
include/dxc/HLSL/DxilModule.h

@@ -27,6 +27,7 @@ namespace llvm {
 class LLVMContext;
 class Module;
 class Function;
+class Instruction;
 class MDTuple;
 class MDOperand;
 class DebugInfoFinder;
@@ -149,6 +150,10 @@ public:
 
   static DxilModule *TryGetDxilModule(llvm::Module *pModule);
 
+  // Return true if the instruction is marked precise or if global
+  // refactoring is disabled.
+  bool IsPrecise(llvm::Instruction *inst);
+
 public:
   // Shader properties.
   class ShaderFlags {

+ 18 - 0
lib/HLSL/DxilMetadataHelper.cpp

@@ -1428,4 +1428,22 @@ void DxilMDHelper::ConstMDTupleToUint32Vector(MDTuple *pTupleMD, std::vector<uns
   }
 }
 
+bool DxilMDHelper::IsMarkedPrecise(Instruction *inst) {
+  int32_t val = 0;
+  if (MDNode *precise = inst->getMetadata(kDxilPreciseAttributeMDName)) {
+    assert(precise->getNumOperands() == 1);
+    val = ConstMDToInt32(precise->getOperand(0));
+  }
+  return val;
+}
+
+void DxilMDHelper::MarkPrecise(Instruction *I) {
+  LLVMContext &Ctx = I->getContext();
+  MDNode *preciseNode = MDNode::get(
+    Ctx,
+    { ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Ctx), 1)) });
+
+  I->setMetadata(DxilMDHelper::kDxilPreciseAttributeMDName, preciseNode);
+}
+
 } // namespace hlsl

+ 6 - 0
lib/HLSL/DxilModule.cpp

@@ -1346,6 +1346,12 @@ hlsl::DxilModule *hlsl::DxilModule::TryGetDxilModule(llvm::Module *pModule) {
   return pDxilModule;
 }
 
+bool DxilModule::IsPrecise(Instruction *inst) {
+  if (m_ShaderFlags.GetDisableMathRefactoring())
+    return true;
+  return DxilMDHelper::IsMarkedPrecise(inst);
+}
+
 } // namespace hlsl
 
 namespace llvm {

+ 2 - 9
lib/HLSL/HLModule.cpp

@@ -1164,18 +1164,11 @@ unsigned HLModule::FindCastOp(bool fromUnsigned, bool toUnsigned,
 }
 
 bool HLModule::HasPreciseAttributeWithMetadata(Instruction *I) {
-  MDNode *preciseNode =
-      I->getMetadata(DxilMDHelper::kDxilPreciseAttributeMDName);
-  return preciseNode != nullptr;
+  return DxilMDHelper::IsMarkedPrecise(I);
 }
 
 void HLModule::MarkPreciseAttributeWithMetadata(Instruction *I) {
-  LLVMContext &Ctx = I->getContext();
-  MDNode *preciseNode = MDNode::get(
-      Ctx,
-      {ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Ctx), 1))});
-
-  I->setMetadata(DxilMDHelper::kDxilPreciseAttributeMDName, preciseNode);
+  return DxilMDHelper::MarkPrecise(I);
 }
 
 void HLModule::ClearPreciseAttributeWithMetadata(Instruction *I) {