aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2008-02-26 17:56:20 +0000
committerDevang Patel <dpatel@apple.com>2008-02-26 17:56:20 +0000
commit2b9c10038706500b1228f494e603070c82cab028 (patch)
tree1e9172d8a609cd1f6b4a5c0f0b07c1ba6dc19896
parent56653e3af65b540d519cfd2e3d7647b8738cec4c (diff)
downloadexternal_llvm-2b9c10038706500b1228f494e603070c82cab028.zip
external_llvm-2b9c10038706500b1228f494e603070c82cab028.tar.gz
external_llvm-2b9c10038706500b1228f494e603070c82cab028.tar.bz2
Optimize most common case by using single RetVal in ReturnInst.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47607 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Instructions.h18
-rw-r--r--lib/VMCore/Instructions.cpp54
2 files changed, 52 insertions, 20 deletions
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index c9329db..70a98d7 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -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; }
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 9a84b54..163601a 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -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;
}