]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
[inline asm] Implement mayLoad and mayStore for inline assembly. In general,
authorChad Rosier <mcrosier@apple.com>
Tue, 30 Oct 2012 19:11:54 +0000 (19:11 +0000)
committerChad Rosier <mcrosier@apple.com>
Tue, 30 Oct 2012 19:11:54 +0000 (19:11 +0000)
the MachineInstr MayLoad/MayLoad flags are based on the tablegen implementation.
For inline assembly, however, we need to compute these based on the constraints.

Revert r166929 as this is no longer needed, but leave the test case in place.
rdar://12033048 and PR13504

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167040 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineInstr.h
include/llvm/InlineAsm.h
lib/CodeGen/MachineVerifier.cpp
lib/CodeGen/ScheduleDAGInstrs.cpp
lib/CodeGen/SelectionDAG/InstrEmitter.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

index eab74bd301977df3e13a97d5a0bcb3c342665c3f..42709012d215d69e6138745afce627850dcaf7f4 100644 (file)
@@ -58,8 +58,10 @@ public:
     NoFlags      = 0,
     FrameSetup   = 1 << 0,              // Instruction is used as a part of
                                         // function frame setup code.
-    InsideBundle = 1 << 1               // Instruction is inside a bundle (not
+    InsideBundle = 1 << 1,              // Instruction is inside a bundle (not
                                         // the first MI in a bundle)
+    MayLoad      = 1 << 2,              // Instruction could possibly read memory.
+    MayStore     = 1 << 3               // Instruction could possibly modify memory.
   };
 private:
   const MCInstrDesc *MCID;              // Instruction descriptor.
@@ -445,7 +447,7 @@ public:
   /// Instructions with this flag set are not necessarily simple load
   /// instructions, they may load a value and modify it, for example.
   bool mayLoad(QueryType Type = AnyInBundle) const {
-    return hasProperty(MCID::MayLoad, Type);
+    return hasProperty(MCID::MayLoad, Type) || (Flags & MayLoad);
   }
 
 
@@ -454,7 +456,7 @@ public:
   /// instructions, they may store a modified value based on their operands, or
   /// may not actually modify anything, for example.
   bool mayStore(QueryType Type = AnyInBundle) const {
-    return hasProperty(MCID::MayStore, Type);
+    return hasProperty(MCID::MayStore, Type) || (Flags & MayStore);
   }
 
   //===--------------------------------------------------------------------===//
index c6e0aab05e7d651f0861e2478fd5d19495a0fea9..b5e0fd4effd6b6d5fda543363d4a179d6cd1e897 100644 (file)
@@ -214,6 +214,8 @@ public:
     Extra_HasSideEffects = 1,
     Extra_IsAlignStack = 2,
     Extra_AsmDialect = 4,
+    Extra_MayLoad = 8,
+    Extra_MayStore = 16,
 
     // Inline asm operands map to multiple SDNode / MachineInstr operands.
     // The first operand is an immediate describing the asm operand, the low
index dca68da2f3e6fff6ef66d9d1e87c5ddfd75dd3a1..69a3ae84ec996368ff524eb4613575e05d55787a 100644 (file)
@@ -707,8 +707,9 @@ void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {
     report("Asm string must be an external symbol", MI);
   if (!MI->getOperand(1).isImm())
     report("Asm flags must be an immediate", MI);
-  // Allowed flags are Extra_HasSideEffects = 1, and Extra_IsAlignStack = 2.
-  if (!isUInt<2>(MI->getOperand(1).getImm()))
+  // Allowed flags are Extra_HasSideEffects = 1, Extra_IsAlignStack = 2,
+  // Extra_AsmDialect = 4, Extra_MayLoad = 8, and Extra_MayStore = 16.
+  if (!isUInt<5>(MI->getOperand(1).getImm()))
     report("Unknown asm flags", &MI->getOperand(1), 1);
 
   assert(InlineAsm::MIOp_FirstOperand == 2 && "Asm format changed");
index 8ea0f8a3eacc7bd182e72d84c472ed0c3673ed16..496473d3a4b2a639287954d1aebee846cf8d803c 100644 (file)
@@ -420,11 +420,6 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
 /// Return true if MI is an instruction we are unable to reason about
 /// (like a call or something with unmodeled side effects).
 static inline bool isGlobalMemoryObject(AliasAnalysis *AA, MachineInstr *MI) {
-  if (MI->isInlineAsm()) {
-    // Until we can tell if an inline assembly instruction accesses
-    // memory, we must assume all such instructions do so.
-    return true;
-  }
   if (MI->isCall() || MI->hasUnmodeledSideEffects() ||
       (MI->hasOrderedMemoryRef() &&
        (!MI->mayLoad() || !MI->isInvariantLoad(AA))))
index d1baa3f7167498b2c3b028ed7d35b710c7fe2b92..5fc71cc22383fd3e5d1e9bfffd1c7d54d1cbe6d0 100644 (file)
@@ -903,6 +903,13 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
                           getZExtValue();
     MI->addOperand(MachineOperand::CreateImm(ExtraInfo));
 
+    // Set the MayLoad and MayStore flags.
+    if (ExtraInfo & InlineAsm::Extra_MayLoad)
+      MI->setFlag(MachineInstr::MayLoad);
+
+    if (ExtraInfo & InlineAsm::Extra_MayStore)
+      MI->setFlag(MachineInstr::MayStore);
+
     // Remember to operand index of the group flags.
     SmallVector<unsigned, 8> GroupIdx;
 
index 85103d5750a096ff3b02f81844f891debccbaaa0..eacba90f0ce00a2424c20cd8caac60e477eaadd0 100644 (file)
@@ -6128,7 +6128,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
   const MDNode *SrcLoc = CS.getInstruction()->getMetadata("srcloc");
   AsmNodeOperands.push_back(DAG.getMDNode(SrcLoc));
 
-  // Remember the HasSideEffect, AlignStack and AsmDialect bits as operand 3.
+  // Remember the HasSideEffect, AlignStack, AsmDialect, MayLoad and MayStore
+  // bits as operand 3.
   unsigned ExtraInfo = 0;
   if (IA->hasSideEffects())
     ExtraInfo |= InlineAsm::Extra_HasSideEffects;
@@ -6136,6 +6137,23 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
     ExtraInfo |= InlineAsm::Extra_IsAlignStack;
   // Set the asm dialect.
   ExtraInfo |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
+
+  // Determine if this InlineAsm MayLoad or MayStore based on the constraints.
+  for (unsigned i = 0, e = TargetConstraints.size(); i != e; ++i) {
+    TargetLowering::AsmOperandInfo &OpInfo = TargetConstraints[i];
+
+    // Compute the constraint code and ConstraintType to use.
+    TLI.ComputeConstraintToUse(OpInfo, SDValue());
+
+    if (OpInfo.ConstraintType == TargetLowering::C_Memory ||
+        OpInfo.ConstraintType == TargetLowering::C_Other) {
+      if (OpInfo.Type == InlineAsm::isInput)
+        ExtraInfo |= InlineAsm::Extra_MayLoad;
+      else if (OpInfo.Type == InlineAsm::isOutput)
+        ExtraInfo |= InlineAsm::Extra_MayStore;
+    }
+  }
+
   AsmNodeOperands.push_back(DAG.getTargetConstant(ExtraInfo,
                                                   TLI.getPointerTy()));