]> granicus.if.org Git - llvm/commitdiff
TableGen: Add IntrHasSideEffects property for intrinsics
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 28 Apr 2017 21:01:46 +0000 (21:01 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 28 Apr 2017 21:01:46 +0000 (21:01 +0000)
The IntrNoMem, IntrReadMem, IntrWriteMem, and IntrArgMemOnly intrinsic
properties differ from their corresponding LLVM IR attributes by specifying
that the intrinsic, in addition to its memory properties, has no other side
effects.

The IntrHasSideEffects flag used in combination with one of the memory flags
listed above, makes it possible to define an intrinsic such that its
properties at the CodeGen layer match its properties at the IR layer.

Patch by Tom Stellard

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

include/llvm/IR/Intrinsics.td
utils/TableGen/CodeGenDAGPatterns.cpp
utils/TableGen/CodeGenIntrinsics.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/IntrinsicEmitter.cpp

index cf60f79ba408ea94a546300e19a41b2a2f2723c1..39b992cd06a876947045ba6fc8d33a248ba5ec9d 100644 (file)
@@ -101,6 +101,15 @@ def IntrConvergent : IntrinsicProperty;
 // This property indicates that the intrinsic is safe to speculate.
 def IntrSpeculatable : IntrinsicProperty;
 
+// This property can be used to override the 'has no other side effects'
+// language of the IntrNoMem, IntrReadMem, IntrWriteMem, and IntrArgMemOnly
+// intrinsic properties.  By default, intrinsics are assumed to have side
+// effects, so this property is only necessary if you have defined one of
+// the memory properties listed above.
+// For this property, 'side effects' has the same meaning as 'side effects'
+// defined by the hasSideEffects property of the TableGen Instruction class.
+def IntrHasSideEffects : IntrinsicProperty;
+
 //===----------------------------------------------------------------------===//
 // Types used by intrinsics.
 //===----------------------------------------------------------------------===//
index 972eb9cd3403ede4e3002b056e8e9831d14b9684..ef2cb4208eae6fcc8021203b947978908ec2176f 100644 (file)
@@ -2828,7 +2828,8 @@ public:
       if (IntInfo->ModRef & CodeGenIntrinsic::MR_Mod)
         mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
 
-      if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem)
+      if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem ||
+          IntInfo->hasSideEffects)
         // ReadWriteMem intrinsics can have other strange effects.
         hasSideEffects = true;
     }
index d126f273a1a993dd8aa79aea3c436ab6a5f05513..24374127f536ad3f22d09f4d979d477438809ab2 100644 (file)
@@ -123,6 +123,10 @@ struct CodeGenIntrinsic {
   /// True if the intrinsic is marked as convergent.
   bool isConvergent;
 
+  /// True if the intrinsic has side effects that aren't captured by any
+  /// of the other flags.
+  bool hasSideEffects;
+
   // True if the intrinsic is marked as speculatable.
   bool isSpeculatable;
 
index aad9005de20f98e2afcccbb553e427319e187aed..d1014a5668a54cb0dfc277bbd8240c2e28ed1095 100644 (file)
@@ -516,6 +516,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
   isNoDuplicate = false;
   isConvergent = false;
   isSpeculatable = false;
+  hasSideEffects = false;
 
   if (DefName.size() <= 4 ||
       std::string(DefName.begin(), DefName.begin() + 4) != "int_")
@@ -656,6 +657,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
       isNoReturn = true;
     else if (Property->getName() == "IntrSpeculatable")
       isSpeculatable = true;
+    else if (Property->getName() == "IntrHasSideEffects")
+      hasSideEffects = true;
     else if (Property->isSubClassOf("NoCapture")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
       ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
index 72f2dce401e52934ce5e12b16f863d7841d1b1d1..1fc18a5dd1d876e2a8f4d7ef8404c82c123ebcc2 100644 (file)
@@ -479,6 +479,9 @@ struct AttributeComparator {
     if (L->isSpeculatable != R->isSpeculatable)
       return R->isSpeculatable;
 
+    if (L->hasSideEffects != R->hasSideEffects)
+      return R->hasSideEffects;
+
     // Try to order by readonly/readnone attribute.
     CodeGenIntrinsic::ModRefBehavior LK = L->ModRef;
     CodeGenIntrinsic::ModRefBehavior RK = R->ModRef;