Added interface to allow clients to create a MemIntrinsicNode for
authorMon P Wang <wangmp@apple.com>
Sat, 1 Nov 2008 20:24:53 +0000 (20:24 +0000)
committerMon P Wang <wangmp@apple.com>
Sat, 1 Nov 2008 20:24:53 +0000 (20:24 +0000)
target intrinsics that touches memory

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

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp

index e6499d87ef0f001a161123d655a6befac5769800..b5cc14e56f84f79c8ce7fc3c8b6c807cd22c87b7 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "llvm/Constants.h"
 #include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include "llvm/CodeGen/RuntimeLibcalls.h"
 #include "llvm/ADT/APFloat.h"
@@ -263,7 +264,27 @@ public:
                                   MVT &IntermediateVT,
                                   unsigned &NumIntermediates,
                                   MVT &RegisterVT) const;
-  
+
+  /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the
+  /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
+  /// this is the case, it returns true and store the intrinsic
+  /// information into the IntrinsicInfo that was passed to the function.
+  typedef struct IntrinsicInfo { 
+    unsigned     opc;         // target opcode
+    MVT          memVT;       // memory VT
+    const Value* ptrVal;      // value representing memory location
+    int          offset;      // offset off of ptrVal 
+    unsigned     align;       // alignment
+    bool         vol;         // is volatile?
+    bool         readMem;     // reads memory?
+    bool         writeMem;    // writes memory?
+  } IntrinisicInfo;
+
+  virtual bool getTgtMemIntrinsic(IntrinsicInfo& Info,
+                                  CallInst &I, unsigned Intrinsic) {
+    return false;
+  }
+
   /// getWidenVectorType: given a vector type, returns the type to widen to
   /// (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself.
   /// If there is no vector type that we want to widen to, returns MVT::Other
index e34e78fca6dc4a8866d2b92648260a8ac6c0165c..738575380d0f68c7c5698f0f4e3637ace65d03bc 100644 (file)
@@ -2577,9 +2577,14 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
       Ops.push_back(getRoot());
     }
   }
-  
-  // Add the intrinsic ID as an integer operand.
-  Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy()));
+
+  // Info is set by getTgtMemInstrinsic
+  TargetLowering::IntrinsicInfo Info;
+  bool IsTgtIntrinsic = TLI.getTgtMemIntrinsic(Info, I, Intrinsic);
+
+  // Add the intrinsic ID as an integer operand if it's not a target intrinsic.  
+  if (!IsTgtIntrinsic)
+    Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy()));
 
   // Add all operands of the call to the operand list.
   for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
@@ -2610,7 +2615,15 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
 
   // Create the node.
   SDValue Result;
-  if (!HasChain)
+  if (IsTgtIntrinsic) {
+    // This is target intrinsic that touches memory
+    Result = DAG.getMemIntrinsicNode(Info.opc, VTList, VTs.size(),
+                                     &Ops[0], Ops.size(),
+                                     Info.memVT, Info.ptrVal, Info.offset,
+                                     Info.align, Info.vol,
+                                     Info.readMem, Info.writeMem);
+  }
+  else if (!HasChain)
     Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VTList, VTs.size(),
                          &Ops[0], Ops.size());
   else if (I.getType() != Type::VoidTy)