From 64d4e6125949ebdc31a488c7ed100373b3c99f15 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Tue, 26 Feb 2008 17:56:20 +0000 Subject: [PATCH] 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 --- include/llvm/Instructions.h | 18 +++++++++++++++ lib/VMCore/Instructions.cpp | 54 ++++++++++++++++++++++++++++----------------- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index c9329db29d7..70a98d78bed 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 &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 9a84b540045..163601a6c13 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 &retVals, Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertBefore) { +ReturnInst::ReturnInst(const std::vector &retVals, + Instruction *InsertBefore) + : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size(), + InsertBefore) { init(retVals); } -ReturnInst::ReturnInst(const std::vector &retVals, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertAtEnd) { +ReturnInst::ReturnInst(const std::vector &retVals, + BasicBlock *InsertAtEnd) + : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size(), + InsertAtEnd) { init(retVals); } ReturnInst::ReturnInst(const std::vector &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(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 &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(V) && @@ -636,18 +646,22 @@ void ReturnInst::init(const std::vector &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; } -- 2.11.0