Misc mid-level changes for new 'fence' instruction.
authorEli Friedman <eli.friedman@gmail.com>
Wed, 27 Jul 2011 01:08:30 +0000 (01:08 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 27 Jul 2011 01:08:30 +0000 (01:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136205 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/AliasAnalysis.h
lib/Transforms/Scalar/DeadStoreElimination.cpp
lib/Transforms/Scalar/LowerAtomic.cpp
lib/Transforms/Scalar/SCCP.cpp
lib/VMCore/Instruction.cpp

index 2701b52393b793ea1287c07992df8b9d0a9db3f2..c86aa03d74594caaa3f0cc914f8b5a37b5ae7077 100644 (file)
@@ -341,6 +341,7 @@ public:
     case Instruction::VAArg:  return getModRefInfo((const VAArgInst*)I, Loc);
     case Instruction::Load:   return getModRefInfo((const LoadInst*)I,  Loc);
     case Instruction::Store:  return getModRefInfo((const StoreInst*)I, Loc);
+    case Instruction::Fence:  return getModRefInfo((const FenceInst*)I, Loc);
     case Instruction::Call:   return getModRefInfo((const CallInst*)I,  Loc);
     case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
     default:                  return NoModRef;
@@ -406,6 +407,19 @@ public:
     return getModRefInfo(S, Location(P, Size));
   }
 
+  /// getModRefInfo (for fences) - Return whether information about whether
+  /// a particular store modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
+    // Conservatively correct.  (We could possibly be a bit smarter if
+    // Loc is a alloca that doesn't escape.)
+    return ModRef;
+  }
+
+  /// getModRefInfo (for fences) - A convenience wrapper.
+  ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){
+    return getModRefInfo(S, Location(P, Size));
+  }
+
   /// getModRefInfo (for va_args) - Return whether information about whether
   /// a particular va_arg modifies or reads the specified memory location.
   ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
index e6089a9a432492117e20fe227f22f29cdce8d19d..a645f9211621c226b46f565e747605a48411b835 100644 (file)
@@ -665,7 +665,7 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
       
       continue;
     }
-    
+
     AliasAnalysis::Location LoadedLoc;
     
     // If we encounter a use of the pointer, it is no longer considered dead
@@ -675,9 +675,12 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
       LoadedLoc = AA->getLocation(V);
     } else if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(BBI)) {
       LoadedLoc = AA->getLocationForSource(MTI);
-    } else {
-      // Not a loading instruction.
+    } else if (!BBI->mayReadOrWriteMemory()) {
+      // Instruction doesn't touch memory.
       continue;
+    } else {
+      // Unknown inst; assume it clobbers everything.
+      break;
     }
 
     // Remove any allocas from the DeadPointer set that are loaded, as this
index 9087b46c138b638b9023d6d02037474622fe3117..7f4d9e9c43ede5d81f22db5b8653308ab8fecb8e 100644 (file)
@@ -115,6 +115,11 @@ static bool LowerAtomicIntrinsic(IntrinsicInst *II) {
   return true;
 }
 
+static bool LowerFenceInst(FenceInst *FI) {
+  FI->eraseFromParent();
+  return true;
+}
+
 namespace {
   struct LowerAtomic : public BasicBlockPass {
     static char ID;
@@ -123,9 +128,13 @@ namespace {
     }
     bool runOnBasicBlock(BasicBlock &BB) {
       bool Changed = false;
-      for (BasicBlock::iterator DI = BB.begin(), DE = BB.end(); DI != DE; )
-        if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(DI++))
+      for (BasicBlock::iterator DI = BB.begin(), DE = BB.end(); DI != DE; ) {
+        Instruction *Inst = DI++;
+        if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst))
           Changed |= LowerAtomicIntrinsic(II);
+        if (FenceInst *FI = dyn_cast<FenceInst>(Inst))
+          Changed |= LowerFenceInst(FI);
+      }
       return Changed;
     }
   };
index 67570e60bb5a8602dff7c34fe2e59e938d103b3f..749ba40a64b83ea550a1280dba1549347a4f6232 100644 (file)
@@ -530,6 +530,7 @@ private:
   void visitCallSite      (CallSite CS);
   void visitUnwindInst    (TerminatorInst &I) { /*returns void*/ }
   void visitUnreachableInst(TerminatorInst &I) { /*returns void*/ }
+  void visitFenceInst     (FenceInst &I) { /*returns void*/ }
   void visitAllocaInst    (Instruction &I) { markOverdefined(&I); }
   void visitVAArgInst     (Instruction &I) { markAnythingOverdefined(&I); }
 
index 4597b575e8d2beeef371869cecb0bca510ff7890..cd8f737e28444069efde470b46674f1233d4eac2 100644 (file)
@@ -209,6 +209,9 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const {
     return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices();
   if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this))
     return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices();
+  if (const FenceInst *FI = dyn_cast<FenceInst>(this))
+    return FI->getOrdering() == cast<FenceInst>(FI)->getOrdering() &&
+           FI->getSynchScope() == cast<FenceInst>(FI)->getSynchScope();
 
   return true;
 }
@@ -249,6 +252,9 @@ bool Instruction::isSameOperationAs(const Instruction *I) const {
     return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices();
   if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this))
     return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices();
+  if (const FenceInst *FI = dyn_cast<FenceInst>(this))
+    return FI->getOrdering() == cast<FenceInst>(FI)->getOrdering() &&
+           FI->getSynchScope() == cast<FenceInst>(FI)->getSynchScope();
 
   return true;
 }
@@ -281,6 +287,7 @@ bool Instruction::mayReadFromMemory() const {
   default: return false;
   case Instruction::VAArg:
   case Instruction::Load:
+  case Instruction::Fence: // FIXME: refine definition of mayReadFromMemory
     return true;
   case Instruction::Call:
     return !cast<CallInst>(this)->doesNotAccessMemory();
@@ -296,6 +303,7 @@ bool Instruction::mayReadFromMemory() const {
 bool Instruction::mayWriteToMemory() const {
   switch (getOpcode()) {
   default: return false;
+  case Instruction::Fence: // FIXME: refine definition of mayWriteToMemory
   case Instruction::Store:
   case Instruction::VAArg:
     return true;
@@ -393,6 +401,7 @@ bool Instruction::isSafeToSpeculativelyExecute() const {
   case Switch:
   case Unwind:
   case Unreachable:
+  case Fence:
     return false; // Misc instructions which have effects
   }
 }