[llvm-commits] [llvm] r47508 - in /llvm/trunk: include/llvm/Instructions.h include/llvm/User.h lib/AsmParser/llvmAsmParser.y lib/VMCore/AsmWriter.cpp lib/VMCore/Instructions.cpp lib/VMCore/Verifier.cpp
Devang Patel
dpatel at apple.com
Fri Feb 22 16:35:18 PST 2008
Author: dpatel
Date: Fri Feb 22 18:35:18 2008
New Revision: 47508
URL: http://llvm.org/viewvc/llvm-project?rev=47508&view=rev
Log:
To support multiple return values, now ret instruction supports multiple operands instead of one aggregate operand.
Modified:
llvm/trunk/include/llvm/Instructions.h
llvm/trunk/include/llvm/User.h
llvm/trunk/lib/AsmParser/llvmAsmParser.y
llvm/trunk/lib/VMCore/AsmWriter.cpp
llvm/trunk/lib/VMCore/Instructions.cpp
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=47508&r1=47507&r2=47508&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Fri Feb 22 18:35:18 2008
@@ -1379,9 +1379,9 @@
/// does not continue in this function any longer.
///
class ReturnInst : public TerminatorInst {
- Use RetVal; // Return Value: null if 'void'.
ReturnInst(const ReturnInst &RI);
void init(Value *RetVal);
+ void init(std::vector<Value *> &RetVals);
public:
// ReturnInst constructors:
@@ -1397,21 +1397,15 @@
// if it was passed NULL.
explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0);
ReturnInst(Value *retVal, BasicBlock *InsertAtEnd);
+ ReturnInst(std::vector<Value *> &retVals);
+ ReturnInst(std::vector<Value *> &retVals, Instruction *InsertBefore);
+ ReturnInst(std::vector<Value *> &retVals, BasicBlock *InsertAtEnd);
explicit ReturnInst(BasicBlock *InsertAtEnd);
+ virtual ~ReturnInst();
virtual ReturnInst *clone() const;
- // Transparently provide more efficient getOperand methods.
- Value *getOperand(unsigned i) const {
- assert(i < getNumOperands() && "getOperand() out of range!");
- return RetVal;
- }
- void setOperand(unsigned i, Value *Val) {
- assert(i < getNumOperands() && "setOperand() out of range!");
- RetVal = Val;
- }
-
- Value *getReturnValue() const { return RetVal; }
+ Value *getReturnValue(unsigned n = 0) const;
unsigned getNumSuccessors() const { return 0; }
Modified: llvm/trunk/include/llvm/User.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/User.h?rev=47508&r1=47507&r2=47508&view=diff
==============================================================================
--- llvm/trunk/include/llvm/User.h (original)
+++ llvm/trunk/include/llvm/User.h Fri Feb 22 18:35:18 2008
@@ -29,8 +29,9 @@
/// OperandList - This is a pointer to the array of Users for this operand.
/// For nodes of fixed arity (e.g. a binary operator) this array will live
/// embedded into the derived class. For nodes of variable arity
- /// (e.g. ConstantArrays, CallInst, PHINodes, etc), this memory will be
- /// dynamically allocated and should be destroyed by the classes virtual dtor.
+ /// (e.g. ConstantArrays, CallInst, PHINodes, ReturnInst etc), this memory
+ /// will be dynamically allocated and should be destroyed by the classes
+ /// virtual dtor.
Use *OperandList;
/// NumOperands - The number of values used by this User.
Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=47508&r1=47507&r2=47508&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original)
+++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Fri Feb 22 18:35:18 2008
@@ -2531,7 +2531,7 @@
$$->push_back($1);
CHECK_FOR_ERROR
}
- | ReturnedVal ',' ConstVal {
+ | ReturnedVal ',' ResolvedVal {
($$=$1)->push_back($3);
CHECK_FOR_ERROR
};
@@ -2580,28 +2580,7 @@
BBTerminatorInst :
RET ReturnedVal { // Return with a result...
- if($2->size() == 1)
- $$ = new ReturnInst($2->back());
- else {
-
- std::vector<const Type*> Elements;
- std::vector<Constant*> Vals;
- for (std::vector<Value *>::iterator I = $2->begin(),
- E = $2->end(); I != E; ++I) {
- Value *V = *I;
- Constant *C = cast<Constant>(V);
- Elements.push_back(V->getType());
- Vals.push_back(C);
- }
-
- const StructType *STy = StructType::get(Elements);
- PATypeHolder *PTy =
- new PATypeHolder(HandleUpRefs(StructType::get(Elements)));
-
- Constant *CS = ConstantStruct::get(STy, Vals); // *$2);
- $$ = new ReturnInst(CS);
- delete PTy;
- }
+ $$ = new ReturnInst(*$2);
delete $2;
CHECK_FOR_ERROR
}
@@ -3174,6 +3153,7 @@
if (!GetResultInst::isValidOperands(TmpVal, $5))
GEN_ERROR("Invalid getresult operands");
$$ = new GetResultInst(TmpVal, $5);
+ delete $2;
CHECK_FOR_ERROR
}
| GETELEMENTPTR Types ValueRef IndexList {
Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=47508&r1=47507&r2=47508&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Fri Feb 22 18:35:18 2008
@@ -1304,23 +1304,8 @@
Out << " }";
writeOperand(I.getOperand(0), false);
Out << ", " << cast<GetResultInst>(I).getIndex();
- } else if (isa<ReturnInst>(I)) {
- if (!Operand)
- Out << " void";
- else {
- if (I.getOperand(0)->getType()->isFirstClassType())
- writeOperand(I.getOperand(0), true);
- else {
- Constant *ROp = cast<Constant>(I.getOperand(0));
- const StructType *STy = cast<StructType>(ROp->getType());
- unsigned NumElems = STy->getNumElements();
- for (unsigned i = 0; i < NumElems; ++i) {
- if (i)
- Out << ",";
- writeOperand(ROp->getOperand(i), true);
- }
- }
- }
+ } else if (isa<ReturnInst>(I) && !Operand) {
+ Out << " void";
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
// Print the calling convention being used.
switch (CI->getCallingConv()) {
Modified: llvm/trunk/lib/VMCore/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=47508&r1=47507&r2=47508&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Instructions.cpp (original)
+++ llvm/trunk/lib/VMCore/Instructions.cpp Fri Feb 22 18:35:18 2008
@@ -573,34 +573,75 @@
ReturnInst::ReturnInst(const ReturnInst &RI)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
- &RetVal, RI.getNumOperands()) {
- if (RI.getNumOperands())
- RetVal.init(RI.RetVal, this);
+ OperandList, 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);
}
ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertBefore) {
init(retVal);
}
ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
init(retVal);
}
ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
}
-
+ReturnInst::ReturnInst(std::vector<Value *> &retVals, Instruction *InsertBefore)
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertBefore) {
+ init(retVals);
+}
+ReturnInst::ReturnInst(std::vector<Value *> &retVals, BasicBlock *InsertAtEnd)
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertAtEnd) {
+ init(retVals);
+}
+ReturnInst::ReturnInst(std::vector<Value *> &retVals)
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size()) {
+ init(retVals);
+}
void ReturnInst::init(Value *retVal) {
if (retVal && retVal->getType() != Type::VoidTy) {
assert(!isa<BasicBlock>(retVal) &&
"Cannot return basic block. Probably using the incorrect ctor");
NumOperands = 1;
- RetVal.init(retVal, this);
+ Use *OL = OperandList = new Use[1];
+ OL[0].init(retVal, this);
+ }
+}
+
+void ReturnInst::init(std::vector<Value *> &retVals) {
+ if (retVals.empty())
+ return;
+
+ NumOperands = retVals.size();
+ if (NumOperands == 1) {
+ Value *V = retVals[0];
+ if (V->getType() == Type::VoidTy)
+ return;
+ }
+
+ Use *OL = OperandList = new Use[NumOperands];
+ for (unsigned i = 0; i < NumOperands; ++i) {
+ Value *V = retVals[i];
+ assert(!isa<BasicBlock>(V) &&
+ "Cannot return basic block. Probably using the incorrect ctor");
+ OL[i].init(V, this);
}
}
+Value *ReturnInst::getReturnValue(unsigned n) const {
+ if (NumOperands)
+ return OperandList[n];
+ else
+ return 0;
+}
+
unsigned ReturnInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
@@ -617,6 +658,10 @@
return 0;
}
+ReturnInst::~ReturnInst() {
+ if (NumOperands)
+ delete [] OperandList;
+}
//===----------------------------------------------------------------------===//
// UnwindInst Implementation
@@ -2759,7 +2804,6 @@
return false;
}
-
// Define these methods here so vtables don't get emitted into every translation
// unit that uses these classes.
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=47508&r1=47507&r2=47508&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Fri Feb 22 18:35:18 2008
@@ -576,14 +576,22 @@
void Verifier::visitReturnInst(ReturnInst &RI) {
Function *F = RI.getParent()->getParent();
- if (RI.getNumOperands() == 0)
+ unsigned N = RI.getNumOperands();
+ if (N == 0)
Assert2(F->getReturnType() == Type::VoidTy,
"Found return instr that returns void in Function of non-void "
"return type!", &RI, F->getReturnType());
- else
+ else if (N == 1)
Assert2(F->getReturnType() == RI.getOperand(0)->getType(),
"Function return type does not match operand "
"type of return inst!", &RI, F->getReturnType());
+ else {
+ const StructType *STy = cast<StructType>(F->getReturnType());
+ for (unsigned i = 0; i < N; i++)
+ Assert2(STy->getElementType(i) == RI.getOperand(i)->getType(),
+ "Function return type does not match operand "
+ "type of return inst!", &RI, F->getReturnType());
+ }
// Check to make sure that the return value has necessary properties for
// terminators...
More information about the llvm-commits
mailing list