Implement constant propogation of shift instructions
authorChris Lattner <sabre@nondot.org>
Mon, 6 May 2002 03:01:37 +0000 (03:01 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 6 May 2002 03:01:37 +0000 (03:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2471 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ConstantHandling.h
lib/Transforms/Scalar/ConstantProp.cpp
lib/Transforms/Scalar/SCCP.cpp
lib/VMCore/ConstantFold.h
lib/VMCore/ConstantFolding.h

index ef0a810b40139c4373a6c45765018b5340364f2e..2203b9728d52eea25f9268f922ce898f1b36aa1d 100644 (file)
@@ -72,6 +72,8 @@ public:
   virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0;
   virtual Constant *div(const Constant *V1, const Constant *V2) const = 0;
   virtual Constant *rem(const Constant *V1, const Constant *V2) const = 0;
+  virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
+  virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
 
   virtual ConstantBool *lessthan(const Constant *V1, 
                                  const Constant *V2) const = 0;
@@ -155,6 +157,16 @@ inline Constant *operator%(const Constant &V1, const Constant &V2) {
   return ConstRules::get(V1)->rem(&V1, &V2);
 }
 
+inline Constant *operator<<(const Constant &V1, const Constant &V2) {
+  assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
+  return ConstRules::get(V1)->shl(&V1, &V2);
+}
+
+inline Constant *operator>>(const Constant &V1, const Constant &V2) {
+  assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
+  return ConstRules::get(V1)->shr(&V1, &V2);
+}
+
 inline ConstantBool *operator<(const Constant &V1, 
                                const Constant &V2) {
   assert(V1.getType() == V2.getType() && "Constant types must be identical!");
@@ -219,4 +231,14 @@ inline Constant *ConstantFoldBinaryInstruction(unsigned Opcode,
   return 0;
 }
 
+inline Constant *ConstantFoldShiftInstruction(unsigned Opcode,
+                                              const Constant *V1, 
+                                              const Constant *V2) {
+  switch (Opcode) {
+  case Instruction::Shl:     return *V1 << *V2;
+  case Instruction::Shr:     return *V1 >> *V2;
+  default:                   return 0;
+  }
+}
+
 #endif
index 77a959910fcc5c2856e969d24b6ceef565c0eb8a..9e519e7cf7710244cb62d416012fc08f941d82da 100644 (file)
@@ -97,6 +97,28 @@ ConstantFoldBinaryInst(BasicBlock *BB, BasicBlock::iterator &II,
   return true;
 }
 
+inline static bool 
+ConstantFoldShiftInst(BasicBlock *BB, BasicBlock::iterator &II,
+                     ShiftInst *Op,
+                     Constant *D1, Constant *D2) {
+  Constant *ReplaceWith = ConstantFoldShiftInstruction(Op->getOpcode(), D1,D2);
+  if (!ReplaceWith) return false;   // Nothing new to change...
+
+  // Replaces all of the uses of a variable with uses of the constant.
+  Op->replaceAllUsesWith(ReplaceWith);
+  
+  // Remove the operator from the list of definitions...
+  Op->getParent()->getInstList().remove(II);
+  
+  // The new constant inherits the old name of the operator...
+  if (Op->hasName())
+    ReplaceWith->setName(Op->getName(), BB->getParent()->getSymbolTableSure());
+  
+  // Delete the operator now...
+  delete Op;
+  return true;
+}
+
 // ConstantFoldTerminator - If a terminator instruction is predicated on a
 // constant value, convert it into an unconditional branch to the constant
 // destination.
@@ -157,12 +179,12 @@ bool ConstantFoldTerminator(BasicBlock *BB, BasicBlock::iterator &II,
 //
 bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
   Instruction *Inst = *II;
-  if (isa<BinaryOperator>(Inst)) {
-    Constant *D1 = dyn_cast<Constant>(Inst->getOperand(0));
-    Constant *D2 = dyn_cast<Constant>(Inst->getOperand(1));
+  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Inst)) {
+    Constant *D1 = dyn_cast<Constant>(BO->getOperand(0));
+    Constant *D2 = dyn_cast<Constant>(BO->getOperand(1));
 
     if (D1 && D2)
-      return ConstantFoldBinaryInst(BB, II, cast<BinaryOperator>(Inst), D1, D2);
+      return ConstantFoldBinaryInst(BB, II, BO, D1, D2);
 
   } else if (CastInst *CI = dyn_cast<CastInst>(Inst)) {
     Constant *D = dyn_cast<Constant>(CI->getOperand(0));
@@ -188,7 +210,14 @@ bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
       delete PN;                                 // Finally, delete the node...
       return true;
     }
+  } else if (ShiftInst *SI = dyn_cast<ShiftInst>(Inst)) {
+    Constant *D1 = dyn_cast<Constant>(SI->getOperand(0));
+    Constant *D2 = dyn_cast<Constant>(SI->getOperand(1));
+
+    if (D1 && D2)
+      return ConstantFoldShiftInst(BB, II, SI, D1, D2);
   }
+
   return false;
 }
 
index 8d1547577b4142729d560d1ef05d0d09a29f1694..015c67a0d228ede9b08230b51d897f5c43109e06 100644 (file)
@@ -502,9 +502,15 @@ void SCCP::visitBinaryOperator(Instruction *I) {
   if (V1State.isOverdefined() || V2State.isOverdefined()) {
     markOverdefined(I);
   } else if (V1State.isConstant() && V2State.isConstant()) {
-    Constant *Result = ConstantFoldBinaryInstruction(I->getOpcode(),
-                                                     V1State.getConstant(),
-                                                     V2State.getConstant());
+    Constant *Result = 0;
+    if (isa<BinaryOperator>(I))
+      Result = ConstantFoldBinaryInstruction(I->getOpcode(),
+                                             V1State.getConstant(),
+                                             V2State.getConstant());
+    else if (isa<ShiftInst>(I))
+      Result = ConstantFoldShiftInstruction(I->getOpcode(),
+                                            V1State.getConstant(),
+                                            V2State.getConstant());
     if (Result)
       markConstant(I, Result);      // This instruction constant folds!
     else
index ef0a810b40139c4373a6c45765018b5340364f2e..2203b9728d52eea25f9268f922ce898f1b36aa1d 100644 (file)
@@ -72,6 +72,8 @@ public:
   virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0;
   virtual Constant *div(const Constant *V1, const Constant *V2) const = 0;
   virtual Constant *rem(const Constant *V1, const Constant *V2) const = 0;
+  virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
+  virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
 
   virtual ConstantBool *lessthan(const Constant *V1, 
                                  const Constant *V2) const = 0;
@@ -155,6 +157,16 @@ inline Constant *operator%(const Constant &V1, const Constant &V2) {
   return ConstRules::get(V1)->rem(&V1, &V2);
 }
 
+inline Constant *operator<<(const Constant &V1, const Constant &V2) {
+  assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
+  return ConstRules::get(V1)->shl(&V1, &V2);
+}
+
+inline Constant *operator>>(const Constant &V1, const Constant &V2) {
+  assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
+  return ConstRules::get(V1)->shr(&V1, &V2);
+}
+
 inline ConstantBool *operator<(const Constant &V1, 
                                const Constant &V2) {
   assert(V1.getType() == V2.getType() && "Constant types must be identical!");
@@ -219,4 +231,14 @@ inline Constant *ConstantFoldBinaryInstruction(unsigned Opcode,
   return 0;
 }
 
+inline Constant *ConstantFoldShiftInstruction(unsigned Opcode,
+                                              const Constant *V1, 
+                                              const Constant *V2) {
+  switch (Opcode) {
+  case Instruction::Shl:     return *V1 << *V2;
+  case Instruction::Shr:     return *V1 >> *V2;
+  default:                   return 0;
+  }
+}
+
 #endif
index ef0a810b40139c4373a6c45765018b5340364f2e..2203b9728d52eea25f9268f922ce898f1b36aa1d 100644 (file)
@@ -72,6 +72,8 @@ public:
   virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0;
   virtual Constant *div(const Constant *V1, const Constant *V2) const = 0;
   virtual Constant *rem(const Constant *V1, const Constant *V2) const = 0;
+  virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
+  virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
 
   virtual ConstantBool *lessthan(const Constant *V1, 
                                  const Constant *V2) const = 0;
@@ -155,6 +157,16 @@ inline Constant *operator%(const Constant &V1, const Constant &V2) {
   return ConstRules::get(V1)->rem(&V1, &V2);
 }
 
+inline Constant *operator<<(const Constant &V1, const Constant &V2) {
+  assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
+  return ConstRules::get(V1)->shl(&V1, &V2);
+}
+
+inline Constant *operator>>(const Constant &V1, const Constant &V2) {
+  assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
+  return ConstRules::get(V1)->shr(&V1, &V2);
+}
+
 inline ConstantBool *operator<(const Constant &V1, 
                                const Constant &V2) {
   assert(V1.getType() == V2.getType() && "Constant types must be identical!");
@@ -219,4 +231,14 @@ inline Constant *ConstantFoldBinaryInstruction(unsigned Opcode,
   return 0;
 }
 
+inline Constant *ConstantFoldShiftInstruction(unsigned Opcode,
+                                              const Constant *V1, 
+                                              const Constant *V2) {
+  switch (Opcode) {
+  case Instruction::Shl:     return *V1 << *V2;
+  case Instruction::Shr:     return *V1 >> *V2;
+  default:                   return 0;
+  }
+}
+
 #endif