Optimize most common case by using single RetVal in ReturnInst.
authorDevang Patel <dpatel@apple.com>
Tue, 26 Feb 2008 17:56:20 +0000 (17:56 +0000)
committerDevang Patel <dpatel@apple.com>
Tue, 26 Feb 2008 17:56:20 +0000 (17:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47607 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Instructions.h
lib/VMCore/Instructions.cpp

index c9329db29d726a06edf95c2537950da8d93e7dcb..70a98d78bed9655349109bd593515c9b2e085766 100644 (file)
@@ -1379,6 +1379,7 @@ public:
 /// does not continue in this function any longer.
 ///
 class ReturnInst : public TerminatorInst {
+  Use RetVal;
   ReturnInst(const ReturnInst &RI);
   void init(Value *RetVal);
   void init(const std::vector<Value *> &RetVals);
@@ -1405,6 +1406,23 @@ public:
 
   virtual ReturnInst *clone() const;
 
+  // Transparently provide more efficient getOperand methods.
+  Value *getOperand(unsigned i) const {
+    assert(i < getNumOperands() && "getOperand() out of range!");
+    if (getNumOperands() == 0 || getNumOperands() == 1)
+      return RetVal;
+    
+    return OperandList[i];
+  }
+
+  void setOperand(unsigned i, Value *Val) {
+    assert(i < getNumOperands() && "setOperand() out of range!");
+    if (i == 0) 
+      RetVal = Val;
+    else
+      OperandList[i] = Val;
+  }
+
   Value *getReturnValue(unsigned n = 0) const;
 
   unsigned getNumSuccessors() const { return 0; }
index 9a84b5400458d41c2c61e089ce74f15a21144462..163601a6c13304d6c11cb44659f65479cbe93caf 100644 (file)
@@ -573,35 +573,43 @@ bool InvokeInst::isStructReturn() const {
 
 ReturnInst::ReturnInst(const ReturnInst &RI)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandList, RI.getNumOperands()) {
+                   &RetVal, RI.getNumOperands()) {
   unsigned N = RI.getNumOperands();
-  Use *OL = OperandList = new Use[N];
-  for (unsigned i = 0; i < N; ++i)
-    OL[i].init(RI.getOperand(i), this);
+  if (N == 1) 
+    RetVal.init(RI.RetVal, this);
+  else if (N) {
+    Use *OL = OperandList = new Use[N];
+    for (unsigned i = 0; i < N; ++i)
+      OL[i].init(RI.getOperand(i), this);
+  }
 }
 
 ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertBefore) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
   init(retVal);
 }
 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
   init(retVal);
 }
 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
 }
 
-ReturnInst::ReturnInst(const std::vector<Value *> &retVals, Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertBefore) {
+ReturnInst::ReturnInst(const std::vector<Value *> &retVals, 
+                       Instruction *InsertBefore)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size(), 
+                   InsertBefore) {
   init(retVals);
 }
-ReturnInst::ReturnInst(const std::vector<Value *> &retVals, BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertAtEnd) {
+ReturnInst::ReturnInst(const std::vector<Value *> &retVals, 
+                       BasicBlock *InsertAtEnd)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size(), 
+                   InsertAtEnd) {
   init(retVals);
 }
 ReturnInst::ReturnInst(const std::vector<Value *> &retVals)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size()) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size()) {
   init(retVals);
 }
 
@@ -610,8 +618,7 @@ void ReturnInst::init(Value *retVal) {
     assert(!isa<BasicBlock>(retVal) &&
            "Cannot return basic block.  Probably using the incorrect ctor");
     NumOperands = 1;
-    Use *OL = OperandList = new Use[1];
-    OL[0].init(retVal, this);
+    RetVal.init(retVal, this);
   }
 }
 
@@ -624,9 +631,12 @@ void ReturnInst::init(const std::vector<Value *> &retVals) {
     Value *V = retVals[0];
     if (V->getType() == Type::VoidTy)
       return;
+    RetVal.init(V, this);
+    return;
   }
 
   Use *OL = OperandList = new Use[NumOperands];
+  RetVal.init(retVals[0], this);
   for (unsigned i = 0; i < NumOperands; ++i) {
     Value *V = retVals[i];
     assert(!isa<BasicBlock>(V) &&
@@ -636,18 +646,22 @@ void ReturnInst::init(const std::vector<Value *> &retVals) {
 }
 
 Value *ReturnInst::getReturnValue(unsigned n) const {
-  if (NumOperands)
-    return OperandList[n];
-  else
+  if (getNumOperands() == 0)
     return 0;
+
+  assert (n < getNumOperands() && "getReturnValue out of range!");
+  if (getNumOperands() == 1)
+    return RetVal;
+  else 
+    return OperandList[n];
 }
 
 unsigned ReturnInst::getNumSuccessorsV() const {
   return getNumSuccessors();
 }
 
-// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
-// emit the vtable for the class in this translation unit.
+/// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
+/// emit the vtable for the class in this translation unit.
 void ReturnInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
   assert(0 && "ReturnInst has no successors!");
 }
@@ -659,7 +673,7 @@ BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
 }
 
 ReturnInst::~ReturnInst() {
-  if (NumOperands)
+  if (NumOperands > 1)
     delete [] OperandList;
 }