llvm.org GIT mirror llvm / 57ef4f4
To support multiple return values, now ret instruction supports multiple operands instead of one aggregate operand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47508 91177308-0d34-0410-b5e6-96231b3b80d8 Devang Patel 12 years ago
6 changed file(s) with 80 addition(s) and 68 deletion(s). Raw diff Collapse all Expand all
13781378 /// does not continue in this function any longer.
13791379 ///
13801380 class ReturnInst : public TerminatorInst {
1381 Use RetVal; // Return Value: null if 'void'.
13821381 ReturnInst(const ReturnInst &RI);
13831382 void init(Value *RetVal);
1383 void init(std::vector &RetVals);
13841384
13851385 public:
13861386 // ReturnInst constructors:
13961396 // if it was passed NULL.
13971397 explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0);
13981398 ReturnInst(Value *retVal, BasicBlock *InsertAtEnd);
1399 ReturnInst(std::vector &retVals);
1400 ReturnInst(std::vector &retVals, Instruction *InsertBefore);
1401 ReturnInst(std::vector &retVals, BasicBlock *InsertAtEnd);
13991402 explicit ReturnInst(BasicBlock *InsertAtEnd);
1403 virtual ~ReturnInst();
14001404
14011405 virtual ReturnInst *clone() const;
14021406
1403 // Transparently provide more efficient getOperand methods.
1404 Value *getOperand(unsigned i) const {
1405 assert(i < getNumOperands() && "getOperand() out of range!");
1406 return RetVal;
1407 }
1408 void setOperand(unsigned i, Value *Val) {
1409 assert(i < getNumOperands() && "setOperand() out of range!");
1410 RetVal = Val;
1411 }
1412
1413 Value *getReturnValue() const { return RetVal; }
1407 Value *getReturnValue(unsigned n = 0) const;
14141408
14151409 unsigned getNumSuccessors() const { return 0; }
14161410
2828 /// OperandList - This is a pointer to the array of Users for this operand.
2929 /// For nodes of fixed arity (e.g. a binary operator) this array will live
3030 /// embedded into the derived class. For nodes of variable arity
31 /// (e.g. ConstantArrays, CallInst, PHINodes, etc), this memory will be
32 /// dynamically allocated and should be destroyed by the classes virtual dtor.
31 /// (e.g. ConstantArrays, CallInst, PHINodes, ReturnInst etc), this memory
32 /// will be dynamically allocated and should be destroyed by the classes
33 /// virtual dtor.
3334 Use *OperandList;
3435
3536 /// NumOperands - The number of values used by this User.
25302530 $$->push_back($1);
25312531 CHECK_FOR_ERROR
25322532 }
2533 | ReturnedVal ',' ConstVal {
2533 | ReturnedVal ',' ResolvedVal {
25342534 ($$=$1)->push_back($3);
25352535 CHECK_FOR_ERROR
25362536 };
25792579
25802580 BBTerminatorInst :
25812581 RET ReturnedVal { // Return with a result...
2582 if($2->size() == 1)
2583 $$ = new ReturnInst($2->back());
2584 else {
2585
2586 std::vector Elements;
2587 std::vector Vals;
2588 for (std::vector::iterator I = $2->begin(),
2589 E = $2->end(); I != E; ++I) {
2590 Value *V = *I;
2591 Constant *C = cast(V);
2592 Elements.push_back(V->getType());
2593 Vals.push_back(C);
2594 }
2595
2596 const StructType *STy = StructType::get(Elements);
2597 PATypeHolder *PTy =
2598 new PATypeHolder(HandleUpRefs(StructType::get(Elements)));
2599
2600 Constant *CS = ConstantStruct::get(STy, Vals); // *$2);
2601 $$ = new ReturnInst(CS);
2602 delete PTy;
2603 }
2582 $$ = new ReturnInst(*$2);
26042583 delete $2;
26052584 CHECK_FOR_ERROR
26062585 }
31733152 if (!GetResultInst::isValidOperands(TmpVal, $5))
31743153 GEN_ERROR("Invalid getresult operands");
31753154 $$ = new GetResultInst(TmpVal, $5);
3155 delete $2;
31763156 CHECK_FOR_ERROR
31773157 }
31783158 | GETELEMENTPTR Types ValueRef IndexList {
13031303 Out << " }";
13041304 writeOperand(I.getOperand(0), false);
13051305 Out << ", " << cast(I).getIndex();
1306 } else if (isa(I)) {
1307 if (!Operand)
1308 Out << " void";
1309 else {
1310 if (I.getOperand(0)->getType()->isFirstClassType())
1311 writeOperand(I.getOperand(0), true);
1312 else {
1313 Constant *ROp = cast(I.getOperand(0));
1314 const StructType *STy = cast(ROp->getType());
1315 unsigned NumElems = STy->getNumElements();
1316 for (unsigned i = 0; i < NumElems; ++i) {
1317 if (i)
1318 Out << ",";
1319 writeOperand(ROp->getOperand(i), true);
1320 }
1321 }
1322 }
1306 } else if (isa(I) && !Operand) {
1307 Out << " void";
13231308 } else if (const CallInst *CI = dyn_cast(&I)) {
13241309 // Print the calling convention being used.
13251310 switch (CI->getCallingConv()) {
572572
573573 ReturnInst::ReturnInst(const ReturnInst &RI)
574574 : TerminatorInst(Type::VoidTy, Instruction::Ret,
575 &RetVal, RI.getNumOperands()) {
576 if (RI.getNumOperands())
577 RetVal.init(RI.RetVal, this);
575 OperandList, RI.getNumOperands()) {
576 unsigned N = RI.getNumOperands();
577 Use *OL = OperandList = new Use[N];
578 for (unsigned i = 0; i < N; ++i)
579 OL[i].init(RI.getOperand(i), this);
578580 }
579581
580582 ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
581 : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
583 : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertBefore) {
582584 init(retVal);
583585 }
584586 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
585 : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
587 : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
586588 init(retVal);
587589 }
588590 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
589 : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
590 }
591
592
591 : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
592 }
593
594 ReturnInst::ReturnInst(std::vector &retVals, Instruction *InsertBefore)
595 : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertBefore) {
596 init(retVals);
597 }
598 ReturnInst::ReturnInst(std::vector &retVals, BasicBlock *InsertAtEnd)
599 : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertAtEnd) {
600 init(retVals);
601 }
602 ReturnInst::ReturnInst(std::vector &retVals)
603 : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size()) {
604 init(retVals);
605 }
593606
594607 void ReturnInst::init(Value *retVal) {
595608 if (retVal && retVal->getType() != Type::VoidTy) {
596609 assert(!isa(retVal) &&
597610 "Cannot return basic block. Probably using the incorrect ctor");
598611 NumOperands = 1;
599 RetVal.init(retVal, this);
600 }
612 Use *OL = OperandList = new Use[1];
613 OL[0].init(retVal, this);
614 }
615 }
616
617 void ReturnInst::init(std::vector &retVals) {
618 if (retVals.empty())
619 return;
620
621 NumOperands = retVals.size();
622 if (NumOperands == 1) {
623 Value *V = retVals[0];
624 if (V->getType() == Type::VoidTy)
625 return;
626 }
627
628 Use *OL = OperandList = new Use[NumOperands];
629 for (unsigned i = 0; i < NumOperands; ++i) {
630 Value *V = retVals[i];
631 assert(!isa(V) &&
632 "Cannot return basic block. Probably using the incorrect ctor");
633 OL[i].init(V, this);
634 }
635 }
636
637 Value *ReturnInst::getReturnValue(unsigned n) const {
638 if (NumOperands)
639 return OperandList[n];
640 else
641 return 0;
601642 }
602643
603644 unsigned ReturnInst::getNumSuccessorsV() const {
616657 return 0;
617658 }
618659
660 ReturnInst::~ReturnInst() {
661 if (NumOperands)
662 delete [] OperandList;
663 }
619664
620665 //===----------------------------------------------------------------------===//
621666 // UnwindInst Implementation
27582803 return false;
27592804 }
27602805
2761
27622806 // Define these methods here so vtables don't get emitted into every translation
27632807 // unit that uses these classes.
27642808
575575
576576 void Verifier::visitReturnInst(ReturnInst &RI) {
577577 Function *F = RI.getParent()->getParent();
578 if (RI.getNumOperands() == 0)
578 unsigned N = RI.getNumOperands();
579 if (N == 0)
579580 Assert2(F->getReturnType() == Type::VoidTy,
580581 "Found return instr that returns void in Function of non-void "
581582 "return type!", &RI, F->getReturnType());
582 else
583 else if (N == 1)
583584 Assert2(F->getReturnType() == RI.getOperand(0)->getType(),
584585 "Function return type does not match operand "
585586 "type of return inst!", &RI, F->getReturnType());
587 else {
588 const StructType *STy = cast(F->getReturnType());
589 for (unsigned i = 0; i < N; i++)
590 Assert2(STy->getElementType(i) == RI.getOperand(i)->getType(),
591 "Function return type does not match operand "
592 "type of return inst!", &RI, F->getReturnType());
593 }
586594
587595 // Check to make sure that the return value has necessary properties for
588596 // terminators...