From lattner at cs.uiuc.edu Mon Sep 5 23:07:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 5 Sep 2005 23:07:28 -0500 Subject: [llvm-commits] CVS: llvm/docs/GettingStarted.html Message-ID: <200509060407.XAA03067@zion.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.119 -> 1.120 --- Log message: Add a requirement, patch contributed by Henrik Bach. --- Diffs of the changes: (+7 -1) GettingStarted.html | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.119 llvm/docs/GettingStarted.html:1.120 --- llvm/docs/GettingStarted.html:1.119 Wed May 18 14:43:25 2005 +++ llvm/docs/GettingStarted.html Mon Sep 5 23:07:15 2005 @@ -349,6 +349,12 @@ + TeXinfo + 4.5 + For building the CFE + + + Flex 2.5.4 LEX compiler @@ -1534,7 +1540,7 @@ Chris Lattner
Reid Spencer
The LLVM Compiler Infrastructure
- Last modified: $Date: 2005/05/18 19:43:25 $ + Last modified: $Date: 2005/09/06 04:07:15 $ From natebegeman at mac.com Mon Sep 5 23:43:14 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 5 Sep 2005 23:43:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200509060443.XAA04990@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.4 -> 1.5 --- Log message: Next round of DAGCombiner changes. This version now passes all the tests I have run so far when run before Legalize. It still needs to pick up the SetCC folds, and nodes that use SetCC. --- Diffs of the changes: (+231 -236) DAGCombiner.cpp | 467 +++++++++++++++++++++++++++----------------------------- 1 files changed, 231 insertions(+), 236 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.4 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.5 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.4 Fri Sep 2 16:18:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Sep 5 23:43:02 2005 @@ -26,10 +26,6 @@ // FIXME: make truncate see through SIGN_EXTEND and AND // FIXME: sext_in_reg(setcc) on targets that return zero or one, and where // EVT != MVT::i1 can drop the sext. -// FIXME: (or x, c) -> c iff maskedValueIsZero(x, ~c) -// FIXME: MaskedValueIsZero can see through SRL, so it should be sufficient to: -//if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) -// return DAG.getConstant(0, VT).Val; // FIXME: (sra (sra x, c1), c2) -> (sra x, c1+c2) // FIXME: verify that getNode can't return extends with an operand whose type // is >= to that of the extend. @@ -75,7 +71,7 @@ /// visit - call the node-specific routine that knows how to fold each /// particular type of node. - SDNode *visit(SDNode *N); + SDOperand visit(SDNode *N); // Visitation implementation - Implement dag node combining for different // node types. The semantics are as follows: @@ -83,41 +79,41 @@ // null - No change was made // otherwise - Node N should be replaced by the returned node. // - SDNode *visitTokenFactor(SDNode *N); - SDNode *visitADD(SDNode *N); - SDNode *visitSUB(SDNode *N); - SDNode *visitMUL(SDNode *N); - SDNode *visitSDIV(SDNode *N); - SDNode *visitUDIV(SDNode *N); - SDNode *visitSREM(SDNode *N); - SDNode *visitUREM(SDNode *N); - SDNode *visitMULHU(SDNode *N); - SDNode *visitMULHS(SDNode *N); - SDNode *visitAND(SDNode *N); - SDNode *visitOR(SDNode *N); - SDNode *visitXOR(SDNode *N); - SDNode *visitSHL(SDNode *N); - SDNode *visitSRA(SDNode *N); - SDNode *visitSRL(SDNode *N); - SDNode *visitCTLZ(SDNode *N); - SDNode *visitCTTZ(SDNode *N); - SDNode *visitCTPOP(SDNode *N); + SDOperand visitTokenFactor(SDNode *N); + SDOperand visitADD(SDNode *N); + SDOperand visitSUB(SDNode *N); + SDOperand visitMUL(SDNode *N); + SDOperand visitSDIV(SDNode *N); + SDOperand visitUDIV(SDNode *N); + SDOperand visitSREM(SDNode *N); + SDOperand visitUREM(SDNode *N); + SDOperand visitMULHU(SDNode *N); + SDOperand visitMULHS(SDNode *N); + SDOperand visitAND(SDNode *N); + SDOperand visitOR(SDNode *N); + SDOperand visitXOR(SDNode *N); + SDOperand visitSHL(SDNode *N); + SDOperand visitSRA(SDNode *N); + SDOperand visitSRL(SDNode *N); + SDOperand visitCTLZ(SDNode *N); + SDOperand visitCTTZ(SDNode *N); + SDOperand visitCTPOP(SDNode *N); // select // select_cc // setcc - SDNode *visitSIGN_EXTEND(SDNode *N); - SDNode *visitZERO_EXTEND(SDNode *N); - SDNode *visitSIGN_EXTEND_INREG(SDNode *N); - SDNode *visitTRUNCATE(SDNode *N); - SDNode *visitSINT_TO_FP(SDNode *N); - SDNode *visitUINT_TO_FP(SDNode *N); - SDNode *visitFP_TO_SINT(SDNode *N); - SDNode *visitFP_TO_UINT(SDNode *N); - SDNode *visitFP_ROUND(SDNode *N); - SDNode *visitFP_ROUND_INREG(SDNode *N); - SDNode *visitFP_EXTEND(SDNode *N); - SDNode *visitFNEG(SDNode *N); - SDNode *visitFABS(SDNode *N); + SDOperand visitSIGN_EXTEND(SDNode *N); + SDOperand visitZERO_EXTEND(SDNode *N); + SDOperand visitSIGN_EXTEND_INREG(SDNode *N); + SDOperand visitTRUNCATE(SDNode *N); + SDOperand visitSINT_TO_FP(SDNode *N); + SDOperand visitUINT_TO_FP(SDNode *N); + SDOperand visitFP_TO_SINT(SDNode *N); + SDOperand visitFP_TO_UINT(SDNode *N); + SDOperand visitFP_ROUND(SDNode *N); + SDOperand visitFP_ROUND_INREG(SDNode *N); + SDOperand visitFP_EXTEND(SDNode *N); + SDOperand visitFNEG(SDNode *N); + SDOperand visitFABS(SDNode *N); // brcond // brcondtwoway // br_cc @@ -242,7 +238,7 @@ // Add all the dag nodes to the worklist. WorkList.insert(WorkList.end(), DAG.allnodes_begin(), DAG.allnodes_end()); - + // while the worklist isn't empty, inspect the node on the end of it and // try and combine it. while (!WorkList.empty()) { @@ -251,7 +247,9 @@ // If N has no uses, it is dead. Make sure to revisit all N's operands once // N is deleted from the DAG, since they too may now be dead. - if (N->use_empty()) { + // FIXME: is there a better way to keep from deleting the dag root because + // we think it has no uses? This works for now... + if (N->use_empty() && N != DAG.getRoot().Val) { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) WorkList.push_back(N->getOperand(i).Val); @@ -260,18 +258,22 @@ continue; } - if (SDNode *Result = visit(N)) { + SDOperand RV = visit(N); + if (RV.Val) { ++NodesCombined; // If we get back the same node we passed in, rather than a new node or // zero, we know that the node must have defined multiple values and // CombineTo was used. Since CombineTo takes care of the worklist // mechanics for us, we have no work to do in this case. - if (Result != N) { - DAG.ReplaceAllUsesWith(N, Result); + if (RV.Val != N) { + std::cerr << "\nReplacing "; N->dump(); + std::cerr << "\nWith: "; RV.Val->dump(); + std::cerr << '\n'; + DAG.ReplaceAllUsesWith(SDOperand(N, 0), RV); // Push the new node and any users onto the worklist - WorkList.push_back(Result); - AddUsersToWorkList(Result); + WorkList.push_back(RV.Val); + AddUsersToWorkList(RV.Val); // Nodes can end up on the worklist more than once. Make sure we do // not process a node that has been replaced. @@ -281,7 +283,7 @@ } } -SDNode *DAGCombiner::visit(SDNode *N) { +SDOperand DAGCombiner::visit(SDNode *N) { switch(N->getOpcode()) { default: break; case ISD::TokenFactor: return visitTokenFactor(N); @@ -317,26 +319,22 @@ case ISD::FNEG: return visitFNEG(N); case ISD::FABS: return visitFABS(N); } - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitTokenFactor(SDNode *N) { - // If the token factor only has one operand, fold TF(x) -> x - if (N->getNumOperands() == 1) - return N->getOperand(0).Val; - +SDOperand DAGCombiner::visitTokenFactor(SDNode *N) { // If the token factor has two operands and one is the entry token, replace // the token factor with the other operand. if (N->getNumOperands() == 2) { if (N->getOperand(0).getOpcode() == ISD::EntryToken) - return N->getOperand(1).Val; + return N->getOperand(1); if (N->getOperand(1).getOpcode() == ISD::EntryToken) - return N->getOperand(0).Val; + return N->getOperand(0); } - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitADD(SDNode *N) { +SDOperand DAGCombiner::visitADD(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); @@ -347,36 +345,36 @@ // fold (add c1, c2) -> c1+c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() + N1C->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold (add x, 0) -> x if (N1C && N1C->isNullValue()) - return N0.Val; + return N0; // fold floating point (add c1, c2) -> c1+c2 if (N0CFP && N1CFP) return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold (A + (-B)) -> A-B if (N1.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(0)).Val; + return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(0)); // fold ((-A) + B) -> B-A if (N0.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(0)).Val; + return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(0)); // fold ((0-A) + B) -> B-A if (N0.getOpcode() == ISD::SUB && isa(N0.getOperand(0)) && cast(N0.getOperand(0))->isNullValue()) - return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(1)).Val; + return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(1)); // fold (A + (0-B)) -> A-B if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) && cast(N1.getOperand(0))->isNullValue()) - return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(1)).Val; + return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(1)); // fold (A+(B-A)) -> B for non-fp types if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1) && !MVT::isFloatingPoint(N1.getValueType())) - return N1.getOperand(0).Val; - return 0; + return N1.getOperand(0); + return SDOperand(); } -SDNode *DAGCombiner::visitSUB(SDNode *N) { +SDOperand DAGCombiner::visitSUB(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0.Val); @@ -387,29 +385,29 @@ // fold (sub c1, c2) -> c1-c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() - N1C->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold (sub x, 0) -> x if (N1C && N1C->isNullValue()) - return N0.Val; + return N0; // fold floating point (sub c1, c2) -> c1-c2 if (N0CFP && N1CFP) return DAG.getConstantFP(N0CFP->getValue() - N1CFP->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold (A+B)-A -> B if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1 && !MVT::isFloatingPoint(N1.getValueType())) - return N0.getOperand(1).Val; + return N0.getOperand(1); // fold (A+B)-B -> A if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 && !MVT::isFloatingPoint(N1.getValueType())) - return N0.getOperand(0).Val; + return N0.getOperand(0); // fold (A-(-B)) -> A+B if (N1.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::ADD, N0.getValueType(), N0, N1.getOperand(0)).Val; - return 0; + return DAG.getNode(ISD::ADD, N0.getValueType(), N0, N1.getOperand(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitMUL(SDNode *N) { +SDOperand DAGCombiner::visitMUL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); @@ -420,27 +418,27 @@ // fold (mul c1, c2) -> c1*c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() * N1C->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold (mul x, 0) -> 0 if (N1C && N1C->isNullValue()) - return N1.Val; + return N1; // fold (mul x, -1) -> 0-x if (N1C && N1C->isAllOnesValue()) return DAG.getNode(ISD::SUB, N->getValueType(0), - DAG.getConstant(0, N->getValueType(0)), N0).Val; + DAG.getConstant(0, N->getValueType(0)), N0); // fold (mul x, (1 << c)) -> x << c if (N1C && isPowerOf2_64(N1C->getValue())) return DAG.getNode(ISD::SHL, N->getValueType(0), N0, DAG.getConstant(Log2_64(N1C->getValue()), - TLI.getShiftAmountTy())).Val; + TLI.getShiftAmountTy())); // fold floating point (mul c1, c2) -> c1*c2 if (N0CFP && N1CFP) return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(), - N->getValueType(0)).Val; - return 0; + N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitSDIV(SDNode *N) { +SDOperand DAGCombiner::visitSDIV(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0.Val); @@ -451,15 +449,15 @@ // fold (sdiv c1, c2) -> c1/c2 if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold floating point (sdiv c1, c2) -> c1/c2 if (N0CFP && N1CFP) return DAG.getConstantFP(N0CFP->getValue() / N1CFP->getValue(), - N->getValueType(0)).Val; - return 0; + N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitUDIV(SDNode *N) { +SDOperand DAGCombiner::visitUDIV(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0.Val); @@ -468,16 +466,16 @@ // fold (udiv c1, c2) -> c1/c2 if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getValue() / N1C->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold (udiv x, (1 << c)) -> x >>u c if (N1C && isPowerOf2_64(N1C->getValue())) return DAG.getNode(ISD::SRL, N->getValueType(0), N0, DAG.getConstant(Log2_64(N1C->getValue()), - TLI.getShiftAmountTy())).Val; - return 0; + TLI.getShiftAmountTy())); + return SDOperand(); } -SDNode *DAGCombiner::visitSREM(SDNode *N) { +SDOperand DAGCombiner::visitSREM(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); @@ -488,15 +486,15 @@ // fold (srem c1, c2) -> c1%c2 if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getSignExtended() % N1C->getSignExtended(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold floating point (srem c1, c2) -> fmod(c1, c2) if (N0CFP && N1CFP) return DAG.getConstantFP(fmod(N0CFP->getValue(),N1CFP->getValue()), - N->getValueType(0)).Val; - return 0; + N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitUREM(SDNode *N) { +SDOperand DAGCombiner::visitUREM(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); @@ -505,101 +503,103 @@ // fold (urem c1, c2) -> c1%c2 if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getValue() % N1C->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // FIXME: c2 power of 2 -> mask? - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitMULHS(SDNode *N) { +SDOperand DAGCombiner::visitMULHS(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N1C = dyn_cast(N1); // fold (mulhs x, 0) -> 0 if (N1C && N1C->isNullValue()) - return N1.Val; - + return N1; // fold (mulhs x, 1) -> (sra x, size(x)-1) if (N1C && N1C->getValue() == 1) return DAG.getNode(ISD::SRA, N0.getValueType(), N0, DAG.getConstant(MVT::getSizeInBits(N0.getValueType())-1, - TLI.getShiftAmountTy())).Val; - return 0; + TLI.getShiftAmountTy())); + return SDOperand(); } -SDNode *DAGCombiner::visitMULHU(SDNode *N) { +SDOperand DAGCombiner::visitMULHU(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N1C = dyn_cast(N1); // fold (mulhu x, 0) -> 0 if (N1C && N1C->isNullValue()) - return N1.Val; - + return N1; // fold (mulhu x, 1) -> 0 if (N1C && N1C->getValue() == 1) - return DAG.getConstant(0, N0.getValueType()).Val; - return 0; + return DAG.getConstant(0, N0.getValueType()); + return SDOperand(); } -SDNode *DAGCombiner::visitAND(SDNode *N) { +SDOperand DAGCombiner::visitAND(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); + unsigned OpSizeInBits = MVT::getSizeInBits(VT); // fold (and c1, c2) -> c1&c2 if (N0C && N1C) - return DAG.getConstant(N0C->getValue() & N1C->getValue(), VT).Val; + return DAG.getConstant(N0C->getValue() & N1C->getValue(), VT); // fold (and x, -1) -> x if (N1C && N1C->isAllOnesValue()) - return N0.Val; - // fold (and x, 0) -> 0 - if (N1C && MaskedValueIsZero(N0, N1C->getValue(), TLI)) - return DAG.getConstant(0, VT).Val; - // fold (and x, mask containing x) -> x - if (N1C) { - uint64_t NotC2 = ~N1C->getValue(); - NotC2 &= ~0ULL >> (64-MVT::getSizeInBits(VT)); - if (MaskedValueIsZero(N0, NotC2, TLI)) - return N0.Val; - } + return N0; + // if (and x, c) is known to be zero, return 0 + if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) + return DAG.getConstant(0, VT); + // fold (and x, c) -> x iff (x & ~c) == 0 + if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)), + TLI)) + return N0; // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { unsigned ExtendBits = MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); if ((N1C->getValue() & (~0ULL << ExtendBits)) == 0) - return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1).Val; + return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1); } // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF if (N0.getOpcode() == ISD::OR) if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) - return N1.Val; - return 0; + return N1; + return SDOperand(); } -SDNode *DAGCombiner::visitOR(SDNode *N) { +SDOperand DAGCombiner::visitOR(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); + MVT::ValueType VT = N1.getValueType(); + unsigned OpSizeInBits = MVT::getSizeInBits(VT); // fold (or c1, c2) -> c1|c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() | N1C->getValue(), - N->getValueType(0)).Val; + N->getValueType(0)); // fold (or x, 0) -> x if (N1C && N1C->isNullValue()) - return N0.Val; + return N0; // fold (or x, -1) -> -1 if (N1C && N1C->isAllOnesValue()) - return N1.Val; - return 0; + return N1; + // fold (or x, c) -> c iff (x & ~c) == 0 + if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)), + TLI)) + return N1; + return SDOperand(); } -SDNode *DAGCombiner::visitXOR(SDNode *N) { +SDOperand DAGCombiner::visitXOR(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); SDOperand LHS, RHS, CC; @@ -609,20 +609,19 @@ // fold (xor c1, c2) -> c1^c2 if (N0C && N1C) - return DAG.getConstant(N0C->getValue() ^ N1C->getValue(), VT).Val; + return DAG.getConstant(N0C->getValue() ^ N1C->getValue(), VT); // fold (xor x, 0) -> x if (N1C && N1C->isNullValue()) - return N0.Val; + return N0; // fold !(x cc y) -> (x !cc y) if (N1C && N1C->getValue() == 1 && isSetCCEquivalent(N0, LHS, RHS, CC)) { bool isInt = MVT::isInteger(LHS.getValueType()); ISD::CondCode NotCC = ISD::getSetCCInverse(cast(CC)->get(), isInt); if (N0.getOpcode() == ISD::SETCC) - return DAG.getSetCC(VT, LHS, RHS, NotCC).Val; + return DAG.getSetCC(VT, LHS, RHS, NotCC); if (N0.getOpcode() == ISD::SELECT_CC) - return DAG.getSelectCC(LHS, RHS, N0.getOperand(2), N0.getOperand(3), - NotCC).Val; + return DAG.getSelectCC(LHS, RHS, N0.getOperand(2),N0.getOperand(3),NotCC); assert(0 && "Unhandled SetCC Equivalent!"); abort(); } @@ -632,7 +631,7 @@ if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS - return DAG.getNode(ISD::AND, VT, LHS, RHS).Val; + return DAG.getNode(ISD::AND, VT, LHS, RHS); } } // fold !(x and y) -> (!x or !y) iff x or y are freely invertible @@ -641,13 +640,13 @@ if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS - return DAG.getNode(ISD::OR, VT, LHS, RHS).Val; + return DAG.getNode(ISD::OR, VT, LHS, RHS); } } - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitSHL(SDNode *N) { +SDOperand DAGCombiner::visitSHL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); @@ -657,29 +656,28 @@ // fold (shl c1, c2) -> c1<getValue() << N1C->getValue(), VT).Val; + return DAG.getConstant(N0C->getValue() << N1C->getValue(), VT); // fold (shl 0, x) -> 0 if (N0C && N0C->isNullValue()) - return N0.Val; + return N0; // fold (shl x, c >= size(x)) -> undef if (N1C && N1C->getValue() >= OpSizeInBits) - return DAG.getNode(ISD::UNDEF, VT).Val; + return DAG.getNode(ISD::UNDEF, VT); // fold (shl x, 0) -> x if (N1C && N1C->isNullValue()) - return N0.Val; + return N0; // if (shl x, c) is known to be zero, return 0 - if (N1C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))>>N1C->getValue(), - TLI)) - return DAG.getConstant(0, VT).Val; + if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) + return DAG.getConstant(0, VT); // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2) if (N1C && N0.getOpcode() == ISD::SHL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getValue(); uint64_t c2 = N1C->getValue(); if (c1 + c2 > OpSizeInBits) - return DAG.getConstant(0, VT).Val; + return DAG.getConstant(0, VT); return DAG.getNode(ISD::SHL, VT, N0.getOperand(0), - DAG.getConstant(c1 + c2, N1.getValueType())).Val; + DAG.getConstant(c1 + c2, N1.getValueType())); } // fold (shl (srl x, c1), c2) -> (shl (and x, -1 << c1), c2-c1) or // (srl (and x, -1 << c1), c1-c2) @@ -691,19 +689,19 @@ DAG.getConstant(~0ULL << c1, VT)); if (c2 > c1) return DAG.getNode(ISD::SHL, VT, Mask, - DAG.getConstant(c2-c1, N1.getValueType())).Val; + DAG.getConstant(c2-c1, N1.getValueType())); else - return DAG.getNode(ISD::SRL, VT, Mask, - DAG.getConstant(c1-c2, N1.getValueType())).Val; + return DAG.getNode(ISD::SRL, VT, Mask, + DAG.getConstant(c1-c2, N1.getValueType())); } // fold (shl (sra x, c1), c1) -> (and x, -1 << c1) if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) return DAG.getNode(ISD::AND, VT, N0.getOperand(0), - DAG.getConstant(~0ULL << N1C->getValue(), VT)).Val; - return 0; + DAG.getConstant(~0ULL << N1C->getValue(), VT)); + return SDOperand(); } -SDNode *DAGCombiner::visitSRA(SDNode *N) { +SDOperand DAGCombiner::visitSRA(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); @@ -713,26 +711,26 @@ // fold (sra c1, c2) -> c1>>c2 if (N0C && N1C) - return DAG.getConstant(N0C->getSignExtended() >> N1C->getValue(), VT).Val; + return DAG.getConstant(N0C->getSignExtended() >> N1C->getValue(), VT); // fold (sra 0, x) -> 0 if (N0C && N0C->isNullValue()) - return N0.Val; + return N0; // fold (sra -1, x) -> -1 if (N0C && N0C->isAllOnesValue()) - return N0.Val; + return N0; // fold (sra x, c >= size(x)) -> undef if (N1C && N1C->getValue() >= OpSizeInBits) - return DAG.getNode(ISD::UNDEF, VT).Val; + return DAG.getNode(ISD::UNDEF, VT); // fold (sra x, 0) -> x if (N1C && N1C->isNullValue()) - return N0.Val; + return N0; // If the sign bit is known to be zero, switch this to a SRL. if (N1C && MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI)) - return DAG.getNode(ISD::SRL, VT, N0, N1).Val; - return 0; + return DAG.getNode(ISD::SRL, VT, N0, N1); + return SDOperand(); } -SDNode *DAGCombiner::visitSRL(SDNode *N) { +SDOperand DAGCombiner::visitSRL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); ConstantSDNode *N0C = dyn_cast(N0); @@ -742,95 +740,94 @@ // fold (srl c1, c2) -> c1 >>u c2 if (N0C && N1C) - return DAG.getConstant(N0C->getValue() >> N1C->getValue(), VT).Val; + return DAG.getConstant(N0C->getValue() >> N1C->getValue(), VT); // fold (srl 0, x) -> 0 if (N0C && N0C->isNullValue()) - return N0.Val; + return N0; // fold (srl x, c >= size(x)) -> undef if (N1C && N1C->getValue() >= OpSizeInBits) - return DAG.getNode(ISD::UNDEF, VT).Val; + return DAG.getNode(ISD::UNDEF, VT); // fold (srl x, 0) -> x if (N1C && N1C->isNullValue()) - return N0.Val; + return N0; // if (srl x, c) is known to be zero, return 0 - if (N1C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))<getValue(), - TLI)) - return DAG.getConstant(0, VT).Val; + if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) + return DAG.getConstant(0, VT); // fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2) if (N1C && N0.getOpcode() == ISD::SRL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getValue(); uint64_t c2 = N1C->getValue(); if (c1 + c2 > OpSizeInBits) - return DAG.getConstant(0, VT).Val; + return DAG.getConstant(0, VT); return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), - DAG.getConstant(c1 + c2, N1.getValueType())).Val; + DAG.getConstant(c1 + c2, N1.getValueType())); } - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitCTLZ(SDNode *N) { +SDOperand DAGCombiner::visitCTLZ(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); // fold (ctlz c1) -> c2 if (N0C) return DAG.getConstant(CountLeadingZeros_64(N0C->getValue()), - N0.getValueType()).Val; - return 0; + N0.getValueType()); + return SDOperand(); } -SDNode *DAGCombiner::visitCTTZ(SDNode *N) { +SDOperand DAGCombiner::visitCTTZ(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); // fold (cttz c1) -> c2 if (N0C) return DAG.getConstant(CountTrailingZeros_64(N0C->getValue()), - N0.getValueType()).Val; - return 0; + N0.getValueType()); + return SDOperand(); } -SDNode *DAGCombiner::visitCTPOP(SDNode *N) { +SDOperand DAGCombiner::visitCTPOP(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); // fold (ctpop c1) -> c2 if (N0C) return DAG.getConstant(CountPopulation_64(N0C->getValue()), - N0.getValueType()).Val; - return 0; + N0.getValueType()); + return SDOperand(); } -SDNode *DAGCombiner::visitSIGN_EXTEND(SDNode *N) { +SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (sext c1) -> c1 if (N0C) - return DAG.getConstant(N0C->getSignExtended(), VT).Val; + return DAG.getConstant(N0C->getSignExtended(), VT); // fold (sext (sext x)) -> (sext x) if (N0.getOpcode() == ISD::SIGN_EXTEND) - return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)).Val; - return 0; + return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitZERO_EXTEND(SDNode *N) { +SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (zext c1) -> c1 if (N0C) - return DAG.getConstant(N0C->getValue(), VT).Val; + return DAG.getConstant(N0C->getValue(), VT); // fold (zext (zext x)) -> (zext x) if (N0.getOpcode() == ISD::ZERO_EXTEND) - return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0)).Val; - return 0; + return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { +SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); SDOperand LHS, RHS, CC; @@ -841,34 +838,34 @@ // fold (sext_in_reg c1) -> c1 if (N0C) { SDOperand Truncate = DAG.getConstant(N0C->getValue(), EVT); - return DAG.getNode(ISD::SIGN_EXTEND, VT, Truncate).Val; + return DAG.getNode(ISD::SIGN_EXTEND, VT, Truncate); } // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt1 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && cast(N0.getOperand(1))->getVT() < EVT) { - return N0.Val; + return N0; } // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && EVT < cast(N0.getOperand(1))->getVT()) { - return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1).Val; + return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1); } // fold (sext_in_reg (assert_sext x)) -> (assert_sext x) if (N0.getOpcode() == ISD::AssertSext && cast(N0.getOperand(1))->getVT() <= EVT) { - return N0.Val; + return N0; } // fold (sext_in_reg (sextload x)) -> (sextload x) if (N0.getOpcode() == ISD::SEXTLOAD && cast(N0.getOperand(3))->getVT() <= EVT) { - return N0.Val; + return N0; } // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or -1 // FIXME: teach isSetCCEquivalent about 0, -1 and then use it here if (N0.getOpcode() == ISD::SETCC && TLI.getSetCCResultContents() == TargetLowering::ZeroOrNegativeOneSetCCResult) - return N0.Val; + return N0; // FIXME: this code is currently just ported over from SelectionDAG.cpp // we probably actually want to handle this in two pieces. Rather than // checking all the top bits for zero, just check the sign bit here and turn @@ -880,91 +877,89 @@ uint64_t Mask = cast(N0.getOperand(1))->getValue(); unsigned NumBits = MVT::getSizeInBits(EVT); if ((Mask & (~0ULL << (NumBits-1))) == 0) - return N0.Val; + return N0; } - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitTRUNCATE(SDNode *N) { +SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // noop truncate if (N0.getValueType() == N->getValueType(0)) - return N0.Val; + return N0; // fold (truncate c1) -> c1 if (N0C) - return DAG.getConstant(N0C->getValue(), VT).Val; + return DAG.getConstant(N0C->getValue(), VT); // fold (truncate (truncate x)) -> (truncate x) if (N0.getOpcode() == ISD::TRUNCATE) - return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)).Val; + return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)); // fold (truncate (ext x)) -> (ext x) or (truncate x) or x if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND){ if (N0.getValueType() < VT) // if the source is smaller than the dest, we still need an extend - return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0)).Val; + return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0)); else if (N0.getValueType() > VT) // if the source is larger than the dest, than we just need the truncate - return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)).Val; + return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)); else // if the source and dest are the same type, we can drop both the extend // and the truncate - return N0.getOperand(0).Val; + return N0.getOperand(0); } - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitSINT_TO_FP(SDNode *N) { +SDOperand DAGCombiner::visitSINT_TO_FP(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); - MVT::ValueType VT = N->getValueType(0); // fold (sint_to_fp c1) -> c1fp if (N0C) - return DAG.getConstantFP(N0C->getSignExtended(), VT).Val; - return 0; + return DAG.getConstantFP(N0C->getSignExtended(), N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitUINT_TO_FP(SDNode *N) { +SDOperand DAGCombiner::visitUINT_TO_FP(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); - MVT::ValueType VT = N->getValueType(0); // fold (uint_to_fp c1) -> c1fp if (N0C) - return DAG.getConstantFP(N0C->getValue(), VT).Val; - return 0; + return DAG.getConstantFP(N0C->getValue(), N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitFP_TO_SINT(SDNode *N) { +SDOperand DAGCombiner::visitFP_TO_SINT(SDNode *N) { ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_to_sint c1fp) -> c1 if (N0CFP) - return DAG.getConstant((int64_t)N0CFP->getValue(), N->getValueType(0)).Val; - return 0; + return DAG.getConstant((int64_t)N0CFP->getValue(), N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitFP_TO_UINT(SDNode *N) { +SDOperand DAGCombiner::visitFP_TO_UINT(SDNode *N) { ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_to_uint c1fp) -> c1 if (N0CFP) - return DAG.getConstant((uint64_t)N0CFP->getValue(), N->getValueType(0)).Val; - return 0; + return DAG.getConstant((uint64_t)N0CFP->getValue(), N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitFP_ROUND(SDNode *N) { +SDOperand DAGCombiner::visitFP_ROUND(SDNode *N) { ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_round c1fp) -> c1fp if (N0CFP) - return DAG.getConstantFP(N0CFP->getValue(), N->getValueType(0)).Val; - return 0; + return DAG.getConstantFP(N0CFP->getValue(), N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitFP_ROUND_INREG(SDNode *N) { +SDOperand DAGCombiner::visitFP_ROUND_INREG(SDNode *N) { SDOperand N0 = N->getOperand(0); MVT::ValueType VT = N->getValueType(0); MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); @@ -972,52 +967,52 @@ // noop fp_round_inreg if (EVT == VT) - return N0.Val; + return N0; // fold (fp_round_inreg c1fp) -> c1fp if (N0CFP) { SDOperand Round = DAG.getConstantFP(N0CFP->getValue(), EVT); - return DAG.getNode(ISD::FP_EXTEND, VT, Round).Val; + return DAG.getNode(ISD::FP_EXTEND, VT, Round); } - return 0; + return SDOperand(); } -SDNode *DAGCombiner::visitFP_EXTEND(SDNode *N) { +SDOperand DAGCombiner::visitFP_EXTEND(SDNode *N) { ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_extend c1fp) -> c1fp if (N0CFP) - return DAG.getConstantFP(N0CFP->getValue(), N->getValueType(0)).Val; - return 0; + return DAG.getConstantFP(N0CFP->getValue(), N->getValueType(0)); + return SDOperand(); } -SDNode *DAGCombiner::visitFNEG(SDNode *N) { +SDOperand DAGCombiner::visitFNEG(SDNode *N) { ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (neg c1) -> -c1 if (N0CFP) - return DAG.getConstantFP(-N0CFP->getValue(), N->getValueType(0)).Val; + return DAG.getConstantFP(-N0CFP->getValue(), N->getValueType(0)); // fold (neg (sub x, y)) -> (sub y, x) if (N->getOperand(0).getOpcode() == ISD::SUB) return DAG.getNode(ISD::SUB, N->getValueType(0), N->getOperand(1), - N->getOperand(0)).Val; + N->getOperand(0)); // fold (neg (neg x)) -> x if (N->getOperand(0).getOpcode() == ISD::FNEG) - return N->getOperand(0).getOperand(0).Val; - return 0; + return N->getOperand(0).getOperand(0); + return SDOperand(); } -SDNode *DAGCombiner::visitFABS(SDNode *N) { +SDOperand DAGCombiner::visitFABS(SDNode *N) { ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fabs c1) -> fabs(c1) if (N0CFP) - return DAG.getConstantFP(fabs(N0CFP->getValue()), N->getValueType(0)).Val; + return DAG.getConstantFP(fabs(N0CFP->getValue()), N->getValueType(0)); // fold (fabs (fabs x)) -> (fabs x) if (N->getOperand(0).getOpcode() == ISD::FABS) - return N->getOperand(0).Val; + return N->getOperand(0); // fold (fabs (fneg x)) -> (fabs x) if (N->getOperand(0).getOpcode() == ISD::FNEG) return DAG.getNode(ISD::FABS, N->getValueType(0), - N->getOperand(0).getOperand(0)).Val; - return 0; + N->getOperand(0).getOperand(0)); + return SDOperand(); } // SelectionDAG::Combine - This is the entry point for the file. From natebegeman at mac.com Tue Sep 6 10:30:24 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Sep 2005 10:30:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCSubtarget.h PowerPCSubtarget.cpp Message-ID: <200509061530.KAA01895@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCSubtarget.h updated: 1.4 -> 1.5 PowerPCSubtarget.cpp updated: 1.6 -> 1.7 --- Log message: Add accessor for 64bit flag, so that we can tell when it is safe to generate the fun in-register fp<->long instructions. --- Diffs of the changes: (+3 -1) PowerPCSubtarget.cpp | 1 + PowerPCSubtarget.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.4 llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.5 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.4 Fri Sep 2 13:33:05 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.h Tue Sep 6 10:30:12 2005 @@ -29,6 +29,7 @@ /// Used by the ISel to turn in optimizations for POWER4-derived architectures bool IsGigaProcessor; + bool Is64Bit; bool HasFSQRT; bool IsAIX; bool IsDarwin; @@ -47,7 +48,7 @@ bool isAIX() const { return IsAIX; } bool isDarwin() const { return IsDarwin; } - + bool is64Bit() const { return Is64Bit; } bool isGigaProcessor() const { return IsGigaProcessor; } }; } // End llvm namespace Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.6 llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.7 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.6 Fri Sep 2 14:27:43 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp Tue Sep 6 10:30:12 2005 @@ -132,6 +132,7 @@ PowerPCSubTypeKV, PowerPCSubTypeKVSize, PowerPCFeatureKV, PowerPCFeatureKVSize); IsGigaProcessor = (Bits & PowerPCFeatureGPUL ) != 0; + Is64Bit = (Bits & PowerPCFeature64Bit) != 0; HasFSQRT = (Bits & PowerPCFeatureFSqrt) != 0; // Set the boolean corresponding to the current target triple, or the default From natebegeman at mac.com Tue Sep 6 10:30:59 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Sep 2005 10:30:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200509061530.KAA01907@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.30 -> 1.31 --- Log message: Add note about future optimization noted in the ppc compiler writer's guide --- Diffs of the changes: (+4 -0) README.txt | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.30 llvm/lib/Target/PowerPC/README.txt:1.31 --- llvm/lib/Target/PowerPC/README.txt:1.30 Wed Aug 24 13:15:24 2005 +++ llvm/lib/Target/PowerPC/README.txt Tue Sep 6 10:30:48 2005 @@ -101,3 +101,7 @@ mode. ===-------------------------------------------------------------------------=== + +Implement Newton-Rhapson method for improving estimate instructions to the +correct accuracy, and implementing divide as multiply by reciprocal when it has +more than one use. Itanium will want this too. From alenhar2 at cs.uiuc.edu Tue Sep 6 12:00:34 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 6 Sep 2005 12:00:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp AlphaISelPattern.cpp Message-ID: <200509061700.MAA03003@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.2 -> 1.3 AlphaISelPattern.cpp updated: 1.168 -> 1.169 --- Log message: Fix up the AssertXext problem, as well as adding it at calls --- Diffs of the changes: (+25 -14) AlphaISelLowering.cpp | 24 ++++++++++++++++-------- AlphaISelPattern.cpp | 15 +++++++++------ 2 files changed, 25 insertions(+), 14 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.2 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.3 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.2 Sun Sep 4 01:12:19 2005 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Tue Sep 6 12:00:23 2005 @@ -135,8 +135,6 @@ Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21}; unsigned args_float[] = { Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; - unsigned added_int = 0; - unsigned added_fp = 0; int count = 0; @@ -156,7 +154,6 @@ case MVT::f64: case MVT::f32: args_float[count] = AddLiveIn(MF, args_float[count], getRegClassFor(VT)); - added_fp |= (1 << count); argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[count], VT); DAG.setRoot(argt.getValue(1)); break; @@ -166,7 +163,6 @@ case MVT::i32: case MVT::i64: args_int[count] = AddLiveIn(MF, args_int[count], getRegClassFor(MVT::i64)); - added_int |= (1 << count); argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[count], MVT::i64); DAG.setRoot(argt.getValue(1)); if (VT != MVT::i64) { @@ -197,7 +193,7 @@ VarArgsOffset = count * 8; std::vector LS; for (int i = 0; i < 6; ++i) { - if (!(added_int & (1 << i))) + if (args_int[i] < 1024) args_int[i] = AddLiveIn(MF, args_int[i], getRegClassFor(MVT::i64)); SDOperand argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[i], MVT::i64); int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); @@ -206,7 +202,7 @@ LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, SDFI, DAG.getSrcValue(NULL))); - if (!(added_fp & (1 << i))) + if (args_float[i] < 1024) args_float[i] = AddLiveIn(MF, args_float[i], getRegClassFor(MVT::f64)); argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[i], MVT::f64); FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); @@ -278,8 +274,12 @@ std::vector RetVals; MVT::ValueType RetTyVT = getValueType(RetTy); + MVT::ValueType ActualRetTyVT = RetTyVT; + if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i32) + ActualRetTyVT = MVT::i64; + if (RetTyVT != MVT::isVoid) - RetVals.push_back(RetTyVT); + RetVals.push_back(ActualRetTyVT); RetVals.push_back(MVT::Other); SDOperand TheCall = SDOperand(DAG.getCall(RetVals, @@ -287,7 +287,15 @@ Chain = TheCall.getValue(RetTyVT != MVT::isVoid); Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, DAG.getConstant(NumBytes, getPointerTy())); - return std::make_pair(TheCall, Chain); + SDOperand RetVal = TheCall; + + if (RetTyVT != ActualRetTyVT) { + RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, + MVT::i64, RetVal, DAG.getValueType(RetTyVT)); + RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); + } + + return std::make_pair(RetVal, Chain); } SDOperand AlphaTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.168 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.169 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.168 Sun Sep 4 01:12:19 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Tue Sep 6 12:00:23 2005 @@ -691,10 +691,16 @@ unsigned &Reg = ExprMap[N]; if (Reg) return Reg; - if (N.getOpcode() != ISD::CALL && N.getOpcode() != ISD::TAILCALL) + switch(N.getOpcode()) { + default: Reg = Result = (N.getValueType() != MVT::Other) ? MakeReg(N.getValueType()) : notIn; - else { + break; + case ISD::AssertSext: + case ISD::AssertZext: + return Reg = SelectExpr(N.getOperand(0)); + case ISD::CALL: + case ISD::TAILCALL: // If this is a call instruction, make sure to prepare ALL of the result // values as well as the chain. if (Node->getNumValues() == 1) @@ -706,6 +712,7 @@ ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn; } + break; } switch (opcode) { @@ -1003,10 +1010,6 @@ switch (Node->getValueType(0)) { default: Node->dump(); assert(0 && "Unknown value type for call result!"); case MVT::Other: return notIn; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: case MVT::i64: BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); break; From lattner at cs.uiuc.edu Tue Sep 6 16:22:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Sep 2005 16:22:26 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/nested-comment.td Message-ID: <200509062122.QAA17342@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: nested-comment.td added (r1.1) --- Log message: new testcase: tblgen should grok this. --- Diffs of the changes: (+12 -0) nested-comment.td | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/TableGen/nested-comment.td diff -c /dev/null llvm/test/Regression/TableGen/nested-comment.td:1.1 *** /dev/null Tue Sep 6 16:22:25 2005 --- llvm/test/Regression/TableGen/nested-comment.td Tue Sep 6 16:22:15 2005 *************** *** 0 **** --- 1,12 ---- + // RUN: tblgen < %s + + /* foo + + / foo + + /*NoReg*/, baz + + + */ + + def X; From lattner at cs.uiuc.edu Tue Sep 6 16:23:20 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Sep 2005 16:23:20 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l Message-ID: <200509062123.QAA17444@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.24 -> 1.25 --- Log message: Tighten up the specification to allow TableGen/nested-comment.td to pass (fixing a bug where / in a /* */ comment would cause it to not close). --- Diffs of the changes: (+3 -3) FileLexer.l | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.24 llvm/utils/TableGen/FileLexer.l:1.25 --- llvm/utils/TableGen/FileLexer.l:1.24 Mon Apr 18 20:11:03 2005 +++ llvm/utils/TableGen/FileLexer.l Tue Sep 6 16:23:09 2005 @@ -214,10 +214,10 @@ "/*" { BEGIN(comment); CommentDepth++; } -[^*/]* /* eat anything that's not a '*' or '/' */ -"*"+[^*/]* /* eat up '*'s not followed by '/'s */ +[^*/]* {} /* eat anything that's not a '*' or '/' */ +"*"+[^*/]* {} /* eat up '*'s not followed by '/'s */ "/*" { ++CommentDepth; } -"/"+[^*]* /* eat up /'s not followed by *'s */ +"/"+[^*/]* {} /* eat up /'s not followed by *'s */ "*"+"/" { if (!--CommentDepth) { BEGIN(INITIAL); } } <> { err() << "Unterminated comment!\n"; exit(1); } From lattner at cs.uiuc.edu Tue Sep 6 16:23:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Sep 2005 16:23:39 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.cpp Message-ID: <200509062123.QAA17479@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.cpp updated: 1.1 -> 1.2 --- Log message: regenerate --- Diffs of the changes: (+88 -84) FileLexer.cpp | 172 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 88 insertions(+), 84 deletions(-) Index: llvm/utils/TableGen/FileLexer.cpp diff -u llvm/utils/TableGen/FileLexer.cpp:1.1 llvm/utils/TableGen/FileLexer.cpp:1.2 --- llvm/utils/TableGen/FileLexer.cpp:1.1 Sat Aug 27 13:50:39 2005 +++ llvm/utils/TableGen/FileLexer.cpp Tue Sep 6 16:23:27 2005 @@ -21,7 +21,7 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /var/cvs/llvm/llvm/utils/TableGen/FileLexer.cpp,v 1.1 2005/08/27 18:50:39 reid Exp $ + * $Header: /var/cvs/llvm/llvm/utils/TableGen/FileLexer.cpp,v 1.2 2005/09/06 21:23:27 lattner Exp $ */ #define FLEX_SCANNER @@ -29,7 +29,6 @@ #define YY_FLEX_MINOR_VERSION 5 #include -#include /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ @@ -43,6 +42,7 @@ #ifdef __cplusplus #include +#include /* Use prototypes in function declarations. */ #define YY_USE_PROTOS @@ -383,19 +383,19 @@ static yyconst short int yy_base[113] = { 0, - 0, 0, 29, 30, 198, 199, 39, 42, 166, 190, - 0, 36, 42, 42, 45, 0, 160, 168, 33, 41, - 167, 164, 42, 159, 0, 57, 61, 70, 45, 184, - 199, 0, 66, 199, 0, 69, 0, 0, 153, 156, - 169, 165, 161, 161, 161, 62, 150, 150, 150, 0, - 75, 76, 199, 171, 199, 79, 151, 70, 0, 0, - 79, 0, 141, 159, 144, 143, 151, 0, 0, 145, - 144, 0, 0, 138, 143, 199, 199, 199, 132, 199, - 0, 136, 0, 145, 132, 0, 136, 0, 0, 118, - 95, 76, 0, 90, 93, 60, 45, 199, 199, 99, + 0, 0, 29, 30, 199, 200, 39, 42, 167, 191, + 0, 36, 42, 42, 45, 0, 161, 169, 33, 41, + 168, 165, 42, 160, 0, 57, 61, 70, 45, 185, + 200, 0, 66, 200, 0, 69, 0, 0, 154, 157, + 170, 166, 162, 162, 162, 62, 151, 151, 151, 0, + 75, 76, 200, 79, 200, 80, 153, 73, 0, 0, + 81, 0, 143, 161, 146, 145, 153, 0, 0, 147, + 146, 0, 0, 140, 145, 200, 200, 200, 134, 200, + 0, 138, 0, 147, 134, 0, 138, 0, 0, 120, + 97, 77, 0, 93, 95, 60, 45, 200, 200, 101, - 105, 107, 110, 116, 122, 128, 131, 137, 140, 145, - 151, 157 + 107, 109, 112, 118, 124, 130, 133, 139, 142, 147, + 153, 159 } ; static yyconst short int yy_def[113] = @@ -415,7 +415,7 @@ 99, 99 } ; -static yyconst short int yy_nxt[236] = +static yyconst short int yy_nxt[237] = { 0, 6, 7, 8, 7, 9, 10, 11, 6, 12, 13, 14, 15, 15, 16, 16, 17, 6, 16, 18, 19, @@ -425,27 +425,27 @@ 98, 35, 33, 33, 33, 33, 33, 33, 43, 41, 36, 42, 44, 47, 52, 98, 53, 48, 55, 57, 56, 28, 28, 28, 58, 37, 33, 33, 33, 61, - 61, 71, 99, 52, 99, 53, 99, 77, 56, 61, - 61, 95, 95, 72, 95, 95, 78, 94, 96, 25, + 61, 71, 99, 52, 99, 53, 99, 99, 99, 56, + 77, 61, 61, 72, 95, 95, 95, 95, 94, 78, - 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, - 30, 32, 32, 38, 38, 38, 50, 50, 93, 50, - 50, 50, 51, 51, 51, 51, 51, 51, 54, 54, - 54, 54, 54, 54, 59, 59, 59, 60, 92, 60, - 60, 60, 60, 62, 62, 63, 63, 63, 63, 63, - 63, 79, 79, 79, 79, 79, 79, 97, 97, 97, - 97, 97, 97, 91, 90, 89, 88, 64, 87, 86, - 85, 84, 83, 82, 81, 80, 64, 76, 99, 75, - 74, 73, 70, 69, 68, 67, 66, 65, 64, 31, - 49, 46, 45, 40, 39, 31, 29, 99, 5, 99, + 96, 25, 25, 25, 25, 25, 25, 30, 30, 30, + 30, 30, 30, 32, 32, 38, 38, 38, 50, 50, + 93, 50, 50, 50, 51, 51, 51, 51, 51, 51, + 54, 54, 54, 54, 54, 54, 59, 59, 59, 60, + 92, 60, 60, 60, 60, 62, 62, 63, 63, 63, + 63, 63, 63, 79, 79, 79, 79, 79, 79, 97, + 97, 97, 97, 97, 97, 91, 90, 89, 88, 64, + 87, 86, 85, 84, 83, 82, 81, 80, 64, 76, + 75, 74, 73, 70, 69, 68, 67, 66, 65, 64, + 31, 49, 46, 45, 40, 39, 31, 29, 99, 5, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99 + 99, 99, 99, 99, 99, 99 } ; -static yyconst short int yy_chk[236] = +static yyconst short int yy_chk[237] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -455,24 +455,24 @@ 97, 13, 14, 14, 14, 15, 15, 15, 20, 19, 14, 19, 20, 23, 26, 96, 26, 23, 27, 29, 27, 28, 28, 28, 29, 14, 33, 33, 33, 36, - 36, 46, 51, 52, 51, 52, 56, 58, 56, 61, - 61, 94, 94, 46, 95, 95, 58, 92, 95, 100, + 36, 46, 51, 52, 51, 52, 54, 56, 54, 56, + 58, 61, 61, 46, 94, 94, 95, 95, 92, 58, - 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, - 101, 102, 102, 103, 103, 103, 104, 104, 91, 104, - 104, 104, 105, 105, 105, 105, 105, 105, 106, 106, - 106, 106, 106, 106, 107, 107, 107, 108, 90, 108, - 108, 108, 108, 109, 109, 110, 110, 110, 110, 110, - 110, 111, 111, 111, 111, 111, 111, 112, 112, 112, - 112, 112, 112, 87, 85, 84, 82, 79, 75, 74, - 71, 70, 67, 66, 65, 64, 63, 57, 54, 49, - 48, 47, 45, 44, 43, 42, 41, 40, 39, 30, - 24, 22, 21, 18, 17, 10, 9, 5, 99, 99, + 95, 100, 100, 100, 100, 100, 100, 101, 101, 101, + 101, 101, 101, 102, 102, 103, 103, 103, 104, 104, + 91, 104, 104, 104, 105, 105, 105, 105, 105, 105, + 106, 106, 106, 106, 106, 106, 107, 107, 107, 108, + 90, 108, 108, 108, 108, 109, 109, 110, 110, 110, + 110, 110, 110, 111, 111, 111, 111, 111, 111, 112, + 112, 112, 112, 112, 112, 87, 85, 84, 82, 79, + 75, 74, 71, 70, 67, 66, 65, 64, 63, 57, + 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, + 30, 24, 22, 21, 18, 17, 10, 9, 5, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99 + 99, 99, 99, 99, 99, 99 } ; static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; @@ -489,7 +489,7 @@ #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 1 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" #define INITIAL 0 /*===-- FileLexer.l - Scanner for TableGen Files ----------------*- C++ -*-===// // @@ -507,7 +507,7 @@ #define YY_NEVER_INTERACTIVE 1 #define comment 1 -#line 30 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 30 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" #include "Record.h" typedef std::pair*> SubClassRefTy; #include "FileParser.h" @@ -792,10 +792,10 @@ YY_DECL { register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; + register char *yy_cp, *yy_bp; register int yy_act; -#line 176 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 176 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" #line 802 "Lexer.cpp" @@ -891,165 +891,165 @@ { /* beginning of action switch */ case 1: YY_RULE_SETUP -#line 178 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 178 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { /* Ignore comments */ } YY_BREAK case 2: YY_RULE_SETUP -#line 180 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 180 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { HandleInclude(yytext); } YY_BREAK case 3: YY_RULE_SETUP -#line 181 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 181 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+2, yytext+yyleng-2); return CODEFRAGMENT; } YY_BREAK case 4: YY_RULE_SETUP -#line 184 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 184 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return INT; } YY_BREAK case 5: YY_RULE_SETUP -#line 185 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 185 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return BIT; } YY_BREAK case 6: YY_RULE_SETUP -#line 186 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 186 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return BITS; } YY_BREAK case 7: YY_RULE_SETUP -#line 187 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 187 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return STRING; } YY_BREAK case 8: YY_RULE_SETUP -#line 188 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 188 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return LIST; } YY_BREAK case 9: YY_RULE_SETUP -#line 189 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 189 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return CODE; } YY_BREAK case 10: YY_RULE_SETUP -#line 190 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 190 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return DAG; } YY_BREAK case 11: YY_RULE_SETUP -#line 192 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 192 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return CLASS; } YY_BREAK case 12: YY_RULE_SETUP -#line 193 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 193 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return DEF; } YY_BREAK case 13: YY_RULE_SETUP -#line 194 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 194 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return FIELD; } YY_BREAK case 14: YY_RULE_SETUP -#line 195 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 195 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return LET; } YY_BREAK case 15: YY_RULE_SETUP -#line 196 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 196 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return IN; } YY_BREAK case 16: YY_RULE_SETUP -#line 198 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 198 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return SRATOK; } YY_BREAK case 17: YY_RULE_SETUP -#line 199 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 199 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return SRLTOK; } YY_BREAK case 18: YY_RULE_SETUP -#line 200 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 200 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return SHLTOK; } YY_BREAK case 19: YY_RULE_SETUP -#line 203 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 203 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext, yytext+yyleng); return ID; } YY_BREAK case 20: YY_RULE_SETUP -#line 205 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 205 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng); return VARNAME; } YY_BREAK case 21: YY_RULE_SETUP -#line 208 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 208 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1); return STRVAL; } YY_BREAK case 22: YY_RULE_SETUP -#line 211 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 211 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.IntVal = ParseInt(Filetext); return INTVAL; } YY_BREAK case 23: YY_RULE_SETUP -#line 213 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 213 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { /* Ignore whitespace */ } YY_BREAK case 24: YY_RULE_SETUP -#line 216 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 216 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { BEGIN(comment); CommentDepth++; } YY_BREAK case 25: YY_RULE_SETUP -#line 217 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" -/* eat anything that's not a '*' or '/' */ +#line 217 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" +{} /* eat anything that's not a '*' or '/' */ YY_BREAK case 26: YY_RULE_SETUP -#line 218 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" -/* eat up '*'s not followed by '/'s */ +#line 218 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" +{} /* eat up '*'s not followed by '/'s */ YY_BREAK case 27: YY_RULE_SETUP -#line 219 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 219 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { ++CommentDepth; } YY_BREAK case 28: YY_RULE_SETUP -#line 220 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" -/* eat up /'s not followed by *'s */ +#line 220 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" +{} /* eat up /'s not followed by *'s */ YY_BREAK case 29: YY_RULE_SETUP -#line 221 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 221 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { if (!--CommentDepth) { BEGIN(INITIAL); } } YY_BREAK case YY_STATE_EOF(comment): -#line 222 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 222 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { err() << "Unterminated comment!\n"; exit(1); } YY_BREAK case 30: YY_RULE_SETUP -#line 224 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 224 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return Filetext[0]; } YY_BREAK case 31: YY_RULE_SETUP -#line 226 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 226 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1056 "Lexer.cpp" @@ -1430,7 +1430,6 @@ #endif /* ifndef YY_NO_UNPUT */ -#ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput() #else @@ -1504,7 +1503,7 @@ return c; } -#endif /* YY_NO_INPUT */ + #ifdef YY_USE_PROTOS void yyrestart( FILE *input_file ) @@ -1615,6 +1614,11 @@ } +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif #ifdef YY_USE_PROTOS void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) @@ -1932,5 +1936,5 @@ return 0; } #endif -#line 226 "/proj/llvm/build/../llvm/utils/TableGen/FileLexer.l" +#line 226 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" From natebegeman at mac.com Tue Sep 6 17:03:39 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Sep 2005 17:03:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp PPC32ISelPattern.cpp PPC32ISelLowering.cpp PPC32ISelLowering.h Message-ID: <200509062203.RAA19794@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.72 -> 1.73 PPC32ISelPattern.cpp updated: 1.176 -> 1.177 PPC32ISelLowering.cpp updated: 1.21 -> 1.22 PPC32ISelLowering.h updated: 1.5 -> 1.6 --- Log message: Implement i64<->fp using the fctidz/fcfid instructions on PowerPC when we are allowed to generate 64-bit-only PowerPC instructions for 32 bit hosts, such as the PowerPC 970. This speeds up 189.lucas from 81.99 to 32.64 seconds. --- Diffs of the changes: (+69 -13) PPC32ISelDAGToDAG.cpp | 13 +++++++++++-- PPC32ISelLowering.cpp | 45 +++++++++++++++++++++++++++++++++++++++------ PPC32ISelLowering.h | 12 +++++++++--- PPC32ISelPattern.cpp | 12 ++++++++++-- 4 files changed, 69 insertions(+), 13 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.72 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.73 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.72 Fri Sep 2 20:17:22 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Sep 6 17:03:27 2005 @@ -795,6 +795,14 @@ Select(N->getOperand(1)), Select(N->getOperand(2))); return SDOperand(N, 0); + case PPCISD::FCFID: + CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0), + Select(N->getOperand(0))); + return SDOperand(N, 0); + case PPCISD::FCTIDZ: + CurDAG->SelectNodeTo(N, PPC::FCTIDZ, N->getValueType(0), + Select(N->getOperand(0))); + return SDOperand(N, 0); case PPCISD::FCTIWZ: CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), Select(N->getOperand(0))); @@ -1085,10 +1093,11 @@ isRotateAndMask(N, Imm, true, SH, MB, ME)) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0).getOperand(0)), - getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); + getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME)); else if (isIntImmediate(N->getOperand(1), Imm)) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)), - getI32Imm(32-Imm), getI32Imm(Imm), getI32Imm(31)); + getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm), + getI32Imm(31)); else CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.176 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.177 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.176 Wed Aug 31 16:09:52 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Tue Sep 6 17:03:27 2005 @@ -817,6 +817,14 @@ Tmp3 = SelectExpr(N.getOperand(2)); BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; + case PPCISD::FCFID: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FCFID, 1, Result).addReg(Tmp1); + return Result; + case PPCISD::FCTIDZ: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FCTIDZ, 1, Result).addReg(Tmp1); + return Result; case PPCISD::FCTIWZ: Tmp1 = SelectExpr(N.getOperand(0)); BuildMI(BB, PPC::FCTIWZ, 1, Result).addReg(Tmp1); @@ -1084,13 +1092,13 @@ if (isOpcWithIntImmediate(N.getOperand(0), ISD::AND, Tmp3) && isRotateAndMask(ISD::SRL, Tmp2, Tmp3, true, SH, MB, ME)) { Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH) + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH & 0x1F) .addImm(MB).addImm(ME); return Result; } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 &= 0x1F; - BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(32-Tmp2) + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm((32-Tmp2) & 0x1F) .addImm(Tmp2).addImm(31); } else { Tmp1 = SelectExpr(N.getOperand(0)); Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.21 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.22 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.21 Fri Sep 2 13:33:05 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Tue Sep 6 17:03:27 2005 @@ -86,11 +86,18 @@ // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); - + // PowerPC does not have [U|S]INT_TO_FP setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand); setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); + // 64 bit PowerPC implementations have instructions to facilitate conversion + // between i64 and fp. + if (TM.getSubtarget().is64Bit()) { + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); + setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); + } + setSetCCResultContents(ZeroOrOneSetCCResult); computeRegisterProperties(); @@ -115,17 +122,43 @@ switch (Op.getOpcode()) { default: assert(0 && "Wasn't expecting to be able to lower this!"); case ISD::FP_TO_SINT: { - assert(Op.getValueType() == MVT::i32 && - MVT::isFloatingPoint(Op.getOperand(0).getValueType())); - Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); + assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType())); + switch (Op.getValueType()) { + default: assert(0 && "Unhandled FP_TO_SINT type in custom expander!"); + case MVT::i32: + Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); + break; + case MVT::i64: + Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Op.getOperand(0)); + break; + } int FrameIdx = DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), Op, FI, DAG.getSrcValue(0)); - FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); - return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); + if (Op.getOpcode() == PPCISD::FCTIDZ) { + Op = DAG.getLoad(MVT::i64, ST, FI, DAG.getSrcValue(0)); + } else { + FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); + Op = DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); + } + return Op; + } + case ISD::SINT_TO_FP: { + assert(MVT::i64 == Op.getOperand(0).getValueType() && + "Unhandled SINT_TO_FP type in custom expander!"); + int FrameIdx = + DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); + SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); + SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), + Op.getOperand(0), FI, DAG.getSrcValue(0)); + SDOperand LD = DAG.getLoad(MVT::f64, ST, FI, DAG.getSrcValue(0)); + SDOperand FP = DAG.getNode(PPCISD::FCFID, MVT::f64, LD); + if (MVT::f32 == Op.getValueType()) + FP = DAG.getNode(ISD::FP_ROUND, MVT::f32, FP); + return FP; } case ISD::SELECT_CC: { // Turn FP only select_cc's into fsel instructions. Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.h diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.5 llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.6 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.5 Wed Aug 31 16:09:52 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.h Tue Sep 6 17:03:27 2005 @@ -29,9 +29,15 @@ /// FSEL, - /// FCTIWZ - The FCTIWZ instruction, taking an f32 or f64 operand, - /// producing an f64 value. - FCTIWZ, + /// FCFID - The FCFID instruction, taking an f64 operand and producing + /// and f64 value containing the FP representation of the integer that + /// was temporarily in the f64 operand. + FCFID, + + /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 + /// operand, producing an f64 value containing the integer representation + /// of that FP value. + FCTIDZ, FCTIWZ, }; } From natebegeman at mac.com Tue Sep 6 17:23:26 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Sep 2005 17:23:26 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/i64_fp.ll Message-ID: <200509062223.RAA21755@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: i64_fp.ll added (r1.1) --- Log message: Test the new 64bit i64<->fp functionality --- Diffs of the changes: (+17 -0) i64_fp.ll | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/i64_fp.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/i64_fp.ll:1.1 *** /dev/null Tue Sep 6 17:23:25 2005 --- llvm/test/Regression/CodeGen/PowerPC/i64_fp.ll Tue Sep 6 17:23:15 2005 *************** *** 0 **** --- 1,17 ---- + ; fcfid and fctid should be generated when the 64bit feature is enabled, but not + ; otherwise. + + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=+64bit | grep 'fcfid' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=+64bit | grep 'fctidz' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5 | grep 'fcfid' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5 | grep 'fctidz' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=-64bit | not grep 'fcfid' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=-64bit | not grep 'fctidz' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g4 | not grep 'fcfid' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g4 | not grep 'fctidz' + + double %X(double %Y) { + %A = cast double %Y to long + %B = cast long %A to double + ret double %B + } From lattner at cs.uiuc.edu Tue Sep 6 17:51:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 6 Sep 2005 17:51:45 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200509062251.RAA22380@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.44 -> 1.45 InstrSelectorEmitter.h updated: 1.26 -> 1.27 --- Log message: Rename a class. These files are being migrated to the new isel and I want to reuse the names --- Diffs of the changes: (+66 -66) InstrSelectorEmitter.cpp | 92 +++++++++++++++++++++++------------------------ InstrSelectorEmitter.h | 40 ++++++++++---------- 2 files changed, 66 insertions(+), 66 deletions(-) Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.44 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.45 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.44 Thu Apr 21 19:00:35 2005 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Tue Sep 6 17:51:34 2005 @@ -33,12 +33,12 @@ //===----------------------------------------------------------------------===// -// TreePatternNode implementation +// TreePatternNodeX implementation // /// getValueRecord - Returns the value of this tree node as a record. For now /// we only allow DefInit's as our leaf values, so this is used. -Record *TreePatternNode::getValueRecord() const { +Record *TreePatternNodeX::getValueRecord() const { DefInit *DI = dynamic_cast(getValue()); assert(DI && "Instruction Selector does not yet support non-def leaves!"); return DI->getDef(); @@ -48,7 +48,7 @@ // updateNodeType - Set the node type of N to VT if VT contains information. If // N already contains a conflicting type, then throw an exception // -bool TreePatternNode::updateNodeType(MVT::ValueType VT, +bool TreePatternNodeX::updateNodeType(MVT::ValueType VT, const std::string &RecName) { if (VT == MVT::Other || getType() == VT) return false; if (getType() == MVT::Other) { @@ -63,7 +63,7 @@ /// are not themselves completely resolved, clone the nonterminal and resolve it /// with the using context we provide. /// -void TreePatternNode::InstantiateNonterminals(InstrSelectorEmitter &ISE) { +void TreePatternNodeX::InstantiateNonterminals(InstrSelectorEmitter &ISE) { if (!isLeaf()) { for (unsigned i = 0, e = getNumChildren(); i != e; ++i) getChild(i)->InstantiateNonterminals(ISE); @@ -87,22 +87,22 @@ /// clone - Make a copy of this tree and all of its children. /// -TreePatternNode *TreePatternNode::clone() const { - TreePatternNode *New; +TreePatternNodeX *TreePatternNodeX::clone() const { + TreePatternNodeX *New; if (isLeaf()) { - New = new TreePatternNode(Value); + New = new TreePatternNodeX(Value); } else { - std::vector > CChildren; + std::vector > CChildren; CChildren.reserve(Children.size()); for (unsigned i = 0, e = getNumChildren(); i != e; ++i) CChildren.push_back(std::make_pair(getChild(i)->clone(),getChildName(i))); - New = new TreePatternNode(Operator, CChildren); + New = new TreePatternNodeX(Operator, CChildren); } New->setType(Type); return New; } -std::ostream &llvm::operator<<(std::ostream &OS, const TreePatternNode &N) { +std::ostream &llvm::operator<<(std::ostream &OS, const TreePatternNodeX &N) { if (N.isLeaf()) return OS << N.getType() << ":" << *N.getValue(); OS << "(" << N.getType() << ":"; @@ -116,7 +116,7 @@ return OS << ")"; } -void TreePatternNode::dump() const { std::cerr << *this; } +void TreePatternNodeX::dump() const { std::cerr << *this; } //===----------------------------------------------------------------------===// // Pattern implementation @@ -168,7 +168,7 @@ /// calculateArgs - Compute the list of all of the arguments to this pattern, /// which are the non-void leaf nodes in this pattern. /// -void Pattern::calculateArgs(TreePatternNode *N, const std::string &Name) { +void Pattern::calculateArgs(TreePatternNodeX *N, const std::string &Name) { if (N->isLeaf() || N->getNumChildren() == 0) { if (N->getType() != MVT::isVoid) Args.push_back(std::make_pair(N, Name)); @@ -197,7 +197,7 @@ return MVT::Other; } -TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) { +TreePatternNodeX *Pattern::ParseTreePattern(DagInit *Dag) { Record *Operator = Dag->getNodeType(); if (Operator->isSubClassOf("ValueType")) { @@ -207,9 +207,9 @@ error("Type cast only valid for a leaf node!"); Init *Arg = Dag->getArg(0); - TreePatternNode *New; + TreePatternNodeX *New; if (DefInit *DI = dynamic_cast(Arg)) { - New = new TreePatternNode(DI); + New = new TreePatternNodeX(DI); // If it's a regclass or something else known, set the type. New->setType(getIntrinsicType(DI->getDef())); } else if (DagInit *DI = dynamic_cast(Arg)) { @@ -228,7 +228,7 @@ if (!ISE.getNodeTypes().count(Operator)) error("Unrecognized node '" + Operator->getName() + "'!"); - std::vector > Children; + std::vector > Children; for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { Init *Arg = Dag->getArg(i); @@ -243,7 +243,7 @@ std::vector >())); --i; // Revisit this node... } else { - Children.push_back(std::make_pair(new TreePatternNode(DefI), + Children.push_back(std::make_pair(new TreePatternNodeX(DefI), Dag->getArgName(i))); // If it's a regclass or something else known, set the type. Children.back().first->setType(getIntrinsicType(R)); @@ -254,7 +254,7 @@ } } - return new TreePatternNode(Operator, Children); + return new TreePatternNodeX(Operator, Children); } void Pattern::InferAllTypes() { @@ -270,7 +270,7 @@ // InferTypes - Perform type inference on the tree, returning true if there // are any remaining untyped nodes and setting MadeChange if any changes were // made. -bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) { +bool Pattern::InferTypes(TreePatternNodeX *N, bool &MadeChange) { if (N->isLeaf()) return N->getType() == MVT::Other; bool AnyUnset = false; @@ -283,7 +283,7 @@ error("Incorrect number of children for " + Operator->getName() + " node!"); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { - TreePatternNode *Child = N->getChild(i); + TreePatternNodeX *Child = N->getChild(i); AnyUnset |= InferTypes(Child, MadeChange); switch (NT.ArgTypes[i]) { @@ -598,21 +598,21 @@ // MoveIdenticalPatterns - Given a tree pattern 'P', move all of the tree // patterns which have the same top-level structure as P from the 'From' list to // the 'To' list. -static void MoveIdenticalPatterns(TreePatternNode *P, - std::vector > &From, - std::vector > &To) { +static void MoveIdenticalPatterns(TreePatternNodeX *P, + std::vector > &From, + std::vector > &To) { assert(!P->isLeaf() && "All leaves are identical!"); - const std::vector &PChildren = P->getChildren(); + const std::vector &PChildren = P->getChildren(); for (unsigned i = 0; i != From.size(); ++i) { - TreePatternNode *N = From[i].second; + TreePatternNodeX *N = From[i].second; assert(P->getOperator() == N->getOperator() &&"Differing operators?"); assert(PChildren.size() == N->getChildren().size() && "Nodes with different arity??"); bool isDifferent = false; for (unsigned c = 0, e = PChildren.size(); c != e; ++c) { - TreePatternNode *PC = PChildren[c]; - TreePatternNode *NC = N->getChild(c); + TreePatternNodeX *PC = PChildren[c]; + TreePatternNodeX *NC = N->getChild(c); if (PC->isLeaf() != NC->isLeaf()) { isDifferent = true; break; @@ -650,7 +650,7 @@ } -static void EmitPatternPredicates(TreePatternNode *Tree, +static void EmitPatternPredicates(TreePatternNodeX *Tree, const std::string &VarName, std::ostream &OS){ OS << " && " << VarName << "->getNodeType() == ISD::" << getNodeName(Tree->getOperator()); @@ -661,7 +661,7 @@ VarName + "->getUse(" + utostr(c)+")", OS); } -static void EmitPatternCosts(TreePatternNode *Tree, const std::string &VarName, +static void EmitPatternCosts(TreePatternNodeX *Tree, const std::string &VarName, std::ostream &OS) { for (unsigned c = 0, e = Tree->getNumChildren(); c != e; ++c) if (Tree->getChild(c)->isLeaf()) { @@ -680,7 +680,7 @@ // pick. This is structured this way to avoid reevaluations of non-obvious // subexpressions. void InstrSelectorEmitter::EmitMatchCosters(std::ostream &OS, - const std::vector > &Patterns, + const std::vector > &Patterns, const std::string &VarPrefix, unsigned IndentAmt) { assert(!Patterns.empty() && "No patterns to emit matchers for!"); @@ -697,9 +697,9 @@ OS << "\n" << Indent << "// Operand matching costs...\n"; std::set ComputedValues; // Avoid duplicate computations... for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { - TreePatternNode *NParent = Patterns[i].second; + TreePatternNodeX *NParent = Patterns[i].second; for (unsigned c = 0, e = NParent->getNumChildren(); c != e; ++c) { - TreePatternNode *N = NParent->getChild(c); + TreePatternNodeX *N = NParent->getChild(c); if (N->isLeaf()) { Record *VR = N->getValueRecord(); const std::string &LeafName = VR->getName(); @@ -723,11 +723,11 @@ #if 0 // Separate out all of the patterns into groups based on what their top-level // signature looks like... - std::vector > PatternsLeft(Patterns); + std::vector > PatternsLeft(Patterns); while (!PatternsLeft.empty()) { // Process all of the patterns that have the same signature as the last // element... - std::vector > Group; + std::vector > Group; MoveIdenticalPatterns(PatternsLeft.back().second, PatternsLeft, Group); assert(!Group.empty() && "Didn't at least pick the source pattern?"); @@ -756,13 +756,13 @@ OS << "0;\n"; // Loop over all of the operands, adding in their costs... - TreePatternNode *N = Group[0].second; - const std::vector &Children = N->getChildren(); + TreePatternNodeX *N = Group[0].second; + const std::vector &Children = N->getChildren(); // If necessary, emit conditionals to check for the appropriate tree // structure here... for (unsigned i = 0, e = Children.size(); i != e; ++i) { - TreePatternNode *C = Children[i]; + TreePatternNodeX *C = Children[i]; if (C->isLeaf()) { // We already calculated the cost for this leaf, add it in now... OS << Indent << " " << LocCostName << " += " @@ -774,7 +774,7 @@ OS << Indent << " if (" << VarPrefix << "_Op" << i << "->getNodeType() == ISD::" << getNodeName(C->getOperator()) << ") {\n"; - std::vector > SubPatterns; + std::vector > SubPatterns; for (unsigned n = 0, e = Group.size(); n != e; ++n) SubPatterns.push_back(std::make_pair(Group[n].first, Group[n].second->getChild(i))); @@ -796,7 +796,7 @@ for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { Pattern *P = Patterns[i].first; - TreePatternNode *PTree = P->getTree(); + TreePatternNodeX *PTree = P->getTree(); unsigned PatternCost = 1; // Check to see if there are any non-leaf elements in the pattern. If so, @@ -838,8 +838,8 @@ } } -static void ReduceAllOperands(TreePatternNode *N, const std::string &Name, - std::vector > &Operands, +static void ReduceAllOperands(TreePatternNodeX *N, const std::string &Name, + std::vector > &Operands, std::ostream &OS) { if (N->isLeaf()) { // If this is a leaf, register or nonterminal reference... @@ -877,7 +877,7 @@ /// name. void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg, const std::string &NameVar, - TreePatternNode *ArgDeclNode, + TreePatternNodeX *ArgDeclNode, Pattern *P, bool PrintArg, std::ostream &OS) { if (DefInit *DI = dynamic_cast(Arg)) { @@ -939,7 +939,7 @@ } static std::string getArgName(Pattern *P, const std::string &ArgName, - const std::vector > &Operands) { + const std::vector > &Operands) { assert(P->getNumArgs() == Operands.size() &&"Argument computation mismatch!"); if (ArgName.empty()) return ""; @@ -1128,7 +1128,7 @@ << " unsigned Pattern = NoMatchPattern;\n" << " unsigned MinCost = ~0U >> 1;\n"; - std::vector > Patterns; + std::vector > Patterns; for (unsigned i = 0, e = J->second.size(); i != e; ++i) Patterns.push_back(std::make_pair(J->second[i], J->second[i]->getTree())); @@ -1170,7 +1170,7 @@ OS << " case " << P->getRecord()->getName() << "_Pattern: {\n" << " // " << *P << "\n"; // Loop over the operands, reducing them... - std::vector > Operands; + std::vector > Operands; ReduceAllOperands(P->getTree(), "N", Operands, OS); // Now that we have reduced all of our operands, and have the values @@ -1218,7 +1218,7 @@ OS << ")"; for (unsigned i = 0, e = Operands.size(); i != e; ++i) { - TreePatternNode *Op = Operands[i].first; + TreePatternNodeX *Op = Operands[i].first; if (Op->isLeaf()) { Record *RV = Op->getValueRecord(); assert(RV->isSubClassOf("RegisterClass") && Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.26 llvm/utils/TableGen/InstrSelectorEmitter.h:1.27 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.26 Thu Apr 21 19:00:35 2005 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Tue Sep 6 17:51:34 2005 @@ -55,9 +55,9 @@ -/// TreePatternNode - Represent a node of the tree patterns. +/// TreePatternNodeX - Represent a node of the tree patterns. /// -class TreePatternNode { +class TreePatternNodeX { /// Operator - The operation that this node represents... this is null if this /// is a leaf. Record *Operator; @@ -68,16 +68,16 @@ /// Children - If this is not a leaf (Operator != 0), this is the subtrees /// that we contain. - std::vector > Children; + std::vector > Children; /// Value - If this node is a leaf, this indicates what the thing is. /// Init *Value; public: - TreePatternNode(Record *o, const std::vector > &c) : Operator(o), Type(MVT::Other), Children(c), Value(0) {} - TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {} + TreePatternNodeX(Init *V) : Operator(0), Type(MVT::Other), Value(V) {} Record *getOperator() const { assert(Operator && "This is a leaf node!"); @@ -89,7 +89,7 @@ bool isLeaf() const { return Operator == 0; } unsigned getNumChildren() const { return Children.size(); } - TreePatternNode *getChild(unsigned c) const { + TreePatternNodeX *getChild(unsigned c) const { assert(Operator != 0 && "This is a leaf node!"); assert(c < Children.size() && "Child access out of range!"); return Children[c].first; @@ -111,7 +111,7 @@ /// clone - Make a copy of this tree and all of its children. /// - TreePatternNode *clone() const; + TreePatternNodeX *clone() const; void dump() const; @@ -127,7 +127,7 @@ bool updateNodeType(MVT::ValueType VT, const std::string &RecName); }; -std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N); +std::ostream &operator<<(std::ostream &OS, const TreePatternNodeX &N); @@ -146,13 +146,13 @@ /// Tree - The tree pattern which corresponds to this pattern. Note that if /// there was a (set) node on the outside level that it has been stripped off. /// - TreePatternNode *Tree; + TreePatternNodeX *Tree; /// Result - If this is an instruction or expander pattern, this is the /// register result, specified with a (set) in the pattern. /// std::string ResultName; // The name of the result value... - TreePatternNode *ResultNode; // The leaf node for the result register... + TreePatternNodeX *ResultNode; // The leaf node for the result register... /// TheRecord - The actual TableGen record corresponding to this pattern. /// @@ -168,7 +168,7 @@ /// Args - This is a list of all of the arguments to this pattern, which are /// the non-void leaf nodes in this pattern. - std::vector > Args; + std::vector > Args; /// ISE - the instruction selector emitter coordinating this madness. /// @@ -181,7 +181,7 @@ InstrSelectorEmitter &ise); /// Pattern - Constructor used for cloning nonterminal patterns - Pattern(TreePatternNode *tree, Record *rec, bool res, + Pattern(TreePatternNodeX *tree, Record *rec, bool res, InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), ResultNode(0), TheRecord(rec), Resolved(res), ISE(ise) { @@ -194,13 +194,13 @@ /// getTree - Return the tree pattern which corresponds to this pattern. /// - TreePatternNode *getTree() const { return Tree; } + TreePatternNodeX *getTree() const { return Tree; } Record *getResult() const { return ResultNode ? ResultNode->getValueRecord() : 0; } const std::string &getResultName() const { return ResultName; } - TreePatternNode *getResultNode() const { return ResultNode; } + TreePatternNodeX *getResultNode() const { return ResultNode; } /// getRecord - Return the actual TableGen record corresponding to this /// pattern. @@ -208,7 +208,7 @@ Record *getRecord() const { return TheRecord; } unsigned getNumArgs() const { return Args.size(); } - TreePatternNode *getArg(unsigned i) const { + TreePatternNodeX *getArg(unsigned i) const { assert(i < Args.size() && "Argument reference out of range!"); return Args[i].first; } @@ -253,10 +253,10 @@ void dump() const; private: - void calculateArgs(TreePatternNode *N, const std::string &Name); + void calculateArgs(TreePatternNodeX *N, const std::string &Name); MVT::ValueType getIntrinsicType(Record *R) const; - TreePatternNode *ParseTreePattern(DagInit *DI); - bool InferTypes(TreePatternNode *N, bool &MadeChange); + TreePatternNodeX *ParseTreePattern(DagInit *DI); + bool InferTypes(TreePatternNodeX *N, bool &MadeChange); }; std::ostream &operator<<(std::ostream &OS, const Pattern &P); @@ -379,7 +379,7 @@ // pick. This is structured this way to avoid reevaluations of non-obvious // subexpressions. void EmitMatchCosters(std::ostream &OS, - const std::vector > &Patterns, + const std::vector > &Patterns, const std::string &VarPrefix, unsigned Indent); /// PrintExpanderOperand - Print out Arg as part of the instruction emission @@ -389,7 +389,7 @@ /// to the BuildMI call. If it is false, we are printing the result register /// name. void PrintExpanderOperand(Init *Arg, const std::string &NameVar, - TreePatternNode *ArgDecl, Pattern *P, + TreePatternNodeX *ArgDecl, Pattern *P, bool PrintArg, std::ostream &OS); }; From natebegeman at mac.com Tue Sep 6 19:15:48 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Sep 2005 19:15:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp SelectionDAGISel.cpp Message-ID: <200509070015.TAA31674@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.5 -> 1.6 SelectionDAGISel.cpp updated: 1.81 -> 1.82 --- Log message: Add an option to the DAG Combiner to enable it for beta runs, and turn on that option for PowerPC's beta. --- Diffs of the changes: (+25 -5) DAGCombiner.cpp | 11 ++++++----- SelectionDAGISel.cpp | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.5 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.6 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.5 Mon Sep 5 23:43:02 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Sep 6 19:15:36 2005 @@ -37,6 +37,7 @@ #define DEBUG_TYPE "dagcombine" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetLowering.h" #include @@ -76,8 +77,8 @@ // Visitation implementation - Implement dag node combining for different // node types. The semantics are as follows: // Return Value: - // null - No change was made - // otherwise - Node N should be replaced by the returned node. + // SDOperand.Val == 0 - No change was made + // otherwise - N should be replaced by the returned Operand. // SDOperand visitTokenFactor(SDNode *N); SDOperand visitADD(SDNode *N); @@ -266,9 +267,9 @@ // CombineTo was used. Since CombineTo takes care of the worklist // mechanics for us, we have no work to do in this case. if (RV.Val != N) { - std::cerr << "\nReplacing "; N->dump(); - std::cerr << "\nWith: "; RV.Val->dump(); - std::cerr << '\n'; + DEBUG(std::cerr << "\nReplacing "; N->dump(); + std::cerr << "\nWith: "; RV.Val->dump(); + std::cerr << '\n'); DAG.ReplaceAllUsesWith(SDOperand(N, 0), RV); // Push the new node and any users onto the worklist Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.81 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.82 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.81 Fri Sep 2 13:41:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Sep 6 19:15:36 2005 @@ -36,6 +36,18 @@ #include using namespace llvm; +// Temporary command line code to enable use of the dag combiner as a beta +// option. +namespace llvm { + bool CombinerEnabled; +} +namespace { + cl::opt + CombineDAG("enable-dag-combiner", cl::Hidden, + cl::desc("Run the DAG combiner before and after Legalize"), + cl::location(CombinerEnabled), + cl::init(false)); +} #ifndef NDEBUG static cl::opt ViewDAGs("view-isel-dags", cl::Hidden, @@ -44,6 +56,7 @@ static const bool ViewDAGs = 0; #endif + namespace llvm { //===--------------------------------------------------------------------===// /// FunctionLoweringInfo - This contains information that is global to a @@ -1234,6 +1247,9 @@ // types that are not supported by the target. BuildSelectionDAG(DAG, LLVMBB, PHINodesToUpdate, FuncInfo); + // Run the DAG combiner in pre-legalize mode, if we are told to do so + if (CombinerEnabled) DAG.Combine(false); + DEBUG(std::cerr << "Lowered selection DAG:\n"); DEBUG(DAG.dump()); @@ -1246,6 +1262,9 @@ if (ViewDAGs) DAG.viewGraph(); + // Run the DAG combiner in post-legalize mode, if we are told to do so + if (CombinerEnabled) DAG.Combine(true); + // Third, instruction select all of the operations to machine code, adding the // code to the MachineBasicBlock. InstructionSelectBasicBlock(DAG); From natebegeman at mac.com Tue Sep 6 19:15:48 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 6 Sep 2005 19:15:48 -0500 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200509070015.TAA31678@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.168 -> 1.169 --- Log message: Add an option to the DAG Combiner to enable it for beta runs, and turn on that option for PowerPC's beta. --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.168 llvm-test/Makefile.programs:1.169 --- llvm-test/Makefile.programs:1.168 Fri Sep 2 14:51:24 2005 +++ llvm-test/Makefile.programs Tue Sep 6 19:15:36 2005 @@ -187,7 +187,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := +LLCBETAOPTION := -enable-dag-combiner endif ifeq ($(ARCH),Alpha) LLCBETAOPTION := -enable-alpha-FTOI -enable-lsr-for-alpha From lattner at cs.uiuc.edu Wed Sep 7 00:36:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 00:36:29 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200509070536.AAA22424@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.60 -> 1.61 --- Log message: Add a new argument to ReplaceAllUsesWith to keep track of nodes deleted by this method --- Diffs of the changes: (+11 -3) SelectionDAG.h | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.60 llvm/include/llvm/CodeGen/SelectionDAG.h:1.61 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.60 Fri Sep 2 14:35:42 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Wed Sep 7 00:36:18 2005 @@ -328,9 +328,16 @@ /// version if 'From' is known to have a single result, use the second /// if you have two nodes with identical results, use the third otherwise. /// - void ReplaceAllUsesWith(SDOperand From, SDOperand Op); - void ReplaceAllUsesWith(SDNode *From, SDNode *To); - void ReplaceAllUsesWith(SDNode *From, const std::vector &To); + /// These methods all take an optional vector, which (if not null) is + /// populated with any nodes that are deleted from the SelectionDAG, due to + /// new equivalences that are discovered. + /// + void ReplaceAllUsesWith(SDOperand From, SDOperand Op, + std::vector *Deleted = 0); + void ReplaceAllUsesWith(SDNode *From, SDNode *To, + std::vector *Deleted = 0); + void ReplaceAllUsesWith(SDNode *From, const std::vector &To, + std::vector *Deleted = 0); /// DeleteNode - Remove the specified node from the system. This node must @@ -343,6 +350,7 @@ void RemoveNodeFromCSEMaps(SDNode *N); SDNode *AddNonLeafNodeToCSEMaps(SDNode *N); void DeleteNodeIfDead(SDNode *N, void *NodeSet); + void DeleteNodeNotInCSEMaps(SDNode *N); /// SimplifySetCC - Try to simplify a setcc built with the specified operands /// and cc. If unable to simplify it, return a null SDOperand. From lattner at cs.uiuc.edu Wed Sep 7 00:37:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 00:37:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509070537.AAA22433@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.186 -> 1.187 --- Log message: Fix a bug nate ran into with replacealluseswith. In the recursive cse case, we were losing a node, causing an assertion to fail. Now we eagerly delete discovered CSE's, and provide an optional vector to keep track of these discovered equivalences. --- Diffs of the changes: (+45 -15) SelectionDAG.cpp | 60 +++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 45 insertions(+), 15 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.186 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.187 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.186 Fri Sep 2 20:04:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Sep 7 00:37:01 2005 @@ -27,6 +27,11 @@ #include using namespace llvm; +// Temporary boolean for testing the dag combiner +namespace llvm { + extern bool CombinerEnabled; +} + static bool isCommutativeBinOp(unsigned Opcode) { switch (Opcode) { case ISD::ADD: @@ -234,6 +239,13 @@ // First take this out of the appropriate CSE map. RemoveNodeFromCSEMaps(N); + // Finally, remove uses due to operands of this node, remove from the + // AllNodes list, and delete the node. + DeleteNodeNotInCSEMaps(N); +} + +void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { + // Remove it from the AllNodes list. for (std::vector::iterator I = AllNodes.begin(); ; ++I) { assert(I != AllNodes.end() && "Node not in AllNodes list??"); @@ -1244,6 +1256,7 @@ ConstantSDNode *N2C = dyn_cast(N2.Val); if (N1C) { if (N2C) { + if (!CombinerEnabled) { uint64_t C1 = N1C->getValue(), C2 = N2C->getValue(); switch (Opcode) { case ISD::ADD: return getConstant(C1 + C2, VT); @@ -1271,7 +1284,7 @@ case ISD::SRA : return getConstant(N1C->getSignExtended() >>(int)C2, VT); default: break; } - + } } else { // Cannonicalize constant to RHS if commutative if (isCommutativeBinOp(Opcode)) { std::swap(N1C, N2C); @@ -1279,6 +1292,7 @@ } } + if (!CombinerEnabled) { switch (Opcode) { default: break; case ISD::SHL: // shl 0, X -> 0 @@ -1295,6 +1309,7 @@ SDOperand Tmp = getNode(ISD::TRUNCATE, cast(N2)->getVT(), N1); return getNode(ISD::SIGN_EXTEND, VT, Tmp); } + } } if (N2C) { @@ -1478,6 +1493,7 @@ ConstantFPSDNode *N2CFP = dyn_cast(N2.Val); if (N1CFP) { if (N2CFP) { + if (!CombinerEnabled) { double C1 = N1CFP->getValue(), C2 = N2CFP->getValue(); switch (Opcode) { case ISD::ADD: return getConstantFP(C1 + C2, VT); @@ -1491,7 +1507,7 @@ break; default: break; } - + } } else { // Cannonicalize constant to RHS if commutative if (isCommutativeBinOp(Opcode)) { std::swap(N1CFP, N2CFP); @@ -1507,10 +1523,12 @@ // Finally, fold operations that do not require constants. switch (Opcode) { case ISD::TokenFactor: + if (!CombinerEnabled) { if (N1.getOpcode() == ISD::EntryToken) return N2; if (N2.getOpcode() == ISD::EntryToken) return N1; + } break; case ISD::AND: @@ -2075,7 +2093,8 @@ /// /// This version assumes From/To have a single result value. /// -void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand ToN) { +void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand ToN, + std::vector *Deleted) { SDNode *From = FromN.Val, *To = ToN.Val; assert(From->getNumValues() == 1 && To->getNumValues() == 1 && "Cannot replace with this method!"); @@ -2097,9 +2116,12 @@ // Now that we have modified U, add it back to the CSE maps. If it already // exists there, recursively merge the results together. - if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) - ReplaceAllUsesWith(U, Existing); + if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { + ReplaceAllUsesWith(U, Existing, Deleted); // U is now dead. + if (Deleted) Deleted->push_back(U); + DeleteNodeNotInCSEMaps(U); + } } } @@ -2109,12 +2131,13 @@ /// This version assumes From/To have matching types and numbers of result /// values. /// -void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) { +void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To, + std::vector *Deleted) { assert(From != To && "Cannot replace uses of with self"); assert(From->getNumValues() == To->getNumValues() && "Cannot use this version of ReplaceAllUsesWith!"); if (From->getNumValues() == 1) { // If possible, use the faster version. - ReplaceAllUsesWith(SDOperand(From, 0), SDOperand(To, 0)); + ReplaceAllUsesWith(SDOperand(From, 0), SDOperand(To, 0), Deleted); return; } @@ -2134,9 +2157,12 @@ // Now that we have modified U, add it back to the CSE maps. If it already // exists there, recursively merge the results together. - if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) - ReplaceAllUsesWith(U, Existing); - // U is now dead. + if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { + ReplaceAllUsesWith(U, Existing, Deleted); + // U is now dead. + if (Deleted) Deleted->push_back(U); + DeleteNodeNotInCSEMaps(U); + } } } @@ -2146,12 +2172,13 @@ /// This version can replace From with any result values. To must match the /// number and types of values returned by From. void SelectionDAG::ReplaceAllUsesWith(SDNode *From, - const std::vector &To) { + const std::vector &To, + std::vector *Deleted) { assert(From->getNumValues() == To.size() && "Incorrect number of values to replace with!"); if (To.size() == 1 && To[0].Val->getNumValues() == 1) { // Degenerate case handled above. - ReplaceAllUsesWith(SDOperand(From, 0), To[0]); + ReplaceAllUsesWith(SDOperand(From, 0), To[0], Deleted); return; } @@ -2172,9 +2199,12 @@ // Now that we have modified U, add it back to the CSE maps. If it already // exists there, recursively merge the results together. - if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) - ReplaceAllUsesWith(U, Existing); - // U is now dead. + if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { + ReplaceAllUsesWith(U, Existing, Deleted); + // U is now dead. + if (Deleted) Deleted->push_back(U); + DeleteNodeNotInCSEMaps(U); + } } } From lattner at cs.uiuc.edu Wed Sep 7 00:44:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 00:44:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SubtargetFeature.cpp Message-ID: <200509070544.AAA22989@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: SubtargetFeature.cpp updated: 1.3 -> 1.4 --- Log message: Print: '' is not a recognized processor for this target (ignoring processor) instead of: is not a recognized processor for this target (ignoring processor) --- Diffs of the changes: (+4 -4) SubtargetFeature.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/SubtargetFeature.cpp diff -u llvm/lib/Target/SubtargetFeature.cpp:1.3 llvm/lib/Target/SubtargetFeature.cpp:1.4 --- llvm/lib/Target/SubtargetFeature.cpp:1.3 Fri Sep 2 14:27:43 2005 +++ llvm/lib/Target/SubtargetFeature.cpp Wed Sep 7 00:44:14 2005 @@ -157,8 +157,8 @@ // Set base feature bits Bits = CPUEntry->Value; } else { - std::cerr << Features[0] - << " is not a recognized processor for this target" + std::cerr << "'" << Features[0] + << "' is not a recognized processor for this target" << " (ignoring processor)" << "\n"; } @@ -177,8 +177,8 @@ if (isEnabled(Feature)) Bits |= FeatureEntry->Value; else Bits &= ~FeatureEntry->Value; } else { - std::cerr << Feature - << " is not a recognized feature for this target" + std::cerr << "'" << Feature + << "' is not a recognized feature for this target" << " (ignoring feature)" << "\n"; } From lattner at cs.uiuc.edu Wed Sep 7 00:45:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 00:45:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp Message-ID: <200509070545.AAA23313@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCSubtarget.cpp updated: 1.7 -> 1.8 --- Log message: On non-apple systems, when using -march=ppc32, do not print: '' is not a recognized processor for this target (ignoring processor) Default to "generic" instead of "" for the default CPU. --- Diffs of the changes: (+1 -1) PowerPCSubtarget.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.7 llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.8 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.7 Tue Sep 6 10:30:12 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp Wed Sep 7 00:45:33 2005 @@ -123,7 +123,7 @@ : StackAlignment(16), IsGigaProcessor(false), IsAIX(false), IsDarwin(false) { // Determine default and user specified characteristics - std::string CPU; + std::string CPU = "generic"; #if defined(__APPLE__) CPU = GetCurrentPowerPCCPU(); #endif From natebegeman at mac.com Wed Sep 7 11:09:30 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 7 Sep 2005 11:09:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200509071609.LAA26227@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.6 -> 1.7 --- Log message: Implement a common missing fold, (add (add x, c1), c2) -> (add x, c1+c2). This restores all of stanford to being identical with and without the dag combiner with the add folding turned off in sd.cpp. --- Diffs of the changes: (+14 -8) DAGCombiner.cpp | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.6 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.7 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.6 Tue Sep 6 19:15:36 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Sep 7 11:09:19 2005 @@ -342,32 +342,38 @@ ConstantSDNode *N1C = dyn_cast(N1); ConstantFPSDNode *N0CFP = dyn_cast(N0); ConstantFPSDNode *N1CFP = dyn_cast(N1); + MVT::ValueType VT = N0.getValueType(); // fold (add c1, c2) -> c1+c2 if (N0C && N1C) - return DAG.getConstant(N0C->getValue() + N1C->getValue(), - N->getValueType(0)); + return DAG.getConstant(N0C->getValue() + N1C->getValue(), VT); // fold (add x, 0) -> x if (N1C && N1C->isNullValue()) return N0; + // fold (add (add x, c1), c2) -> (add x, c1+c2) + if (N1C && N0.getOpcode() == ISD::ADD && + N0.getOperand(1).getOpcode() == ISD::Constant) + return DAG.getNode(ISD::ADD, VT, N0.getOperand(0), + DAG.getConstant(N1C->getValue() + + cast(N0.getOperand(1))->getValue(), + VT)); // fold floating point (add c1, c2) -> c1+c2 if (N0CFP && N1CFP) - return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), - N->getValueType(0)); + return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), VT); // fold (A + (-B)) -> A-B if (N1.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(0)); + return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(0)); // fold ((-A) + B) -> B-A if (N0.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(0)); + return DAG.getNode(ISD::SUB, VT, N1, N0.getOperand(0)); // fold ((0-A) + B) -> B-A if (N0.getOpcode() == ISD::SUB && isa(N0.getOperand(0)) && cast(N0.getOperand(0))->isNullValue()) - return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(1)); + return DAG.getNode(ISD::SUB, VT, N1, N0.getOperand(1)); // fold (A + (0-B)) -> A-B if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) && cast(N1.getOperand(0))->isNullValue()) - return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(1)); + return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(1)); // fold (A+(B-A)) -> B for non-fp types if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1) && !MVT::isFloatingPoint(N1.getValueType())) From lattner at cs.uiuc.edu Wed Sep 7 12:34:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 12:34:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200509071734.MAA27918@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.145 -> 1.146 --- Log message: Fix a bug that Tzu-Chien Chiu noticed: live interval analysis does NOT preserve livevar --- Diffs of the changes: (+0 -1) LiveIntervalAnalysis.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.145 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.146 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.145 Thu Sep 1 19:20:32 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Sep 7 12:34:39 2005 @@ -62,7 +62,6 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); AU.addRequired(); AU.addPreservedID(PHIEliminationID); AU.addRequiredID(PHIEliminationID); From natebegeman at mac.com Wed Sep 7 18:26:04 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 7 Sep 2005 18:26:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp SelectionDAG.cpp Message-ID: <200509072326.SAA30639@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.7 -> 1.8 SelectionDAG.cpp updated: 1.187 -> 1.188 --- Log message: Another round of dag combiner changes. This fixes some missing XOR folds as well as fixing how we replace old values with new values. --- Diffs of the changes: (+48 -17) DAGCombiner.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++------------- SelectionDAG.cpp | 8 +++---- 2 files changed, 48 insertions(+), 17 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.7 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.8 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.7 Wed Sep 7 11:09:19 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Sep 7 18:25:52 2005 @@ -223,11 +223,11 @@ return false; } -// isInvertibleForFree - Return true if there is no cost to emitting the logical -// inverse of this node. -static bool isInvertibleForFree(SDOperand N) { +// isOneUseSetCC - Return true if this is a SetCC-equivalent operation with only +// one use. If this is true, it allows the users to invert the operation for +// free when it is profitable to do so. +static bool isOneUseSetCC(SDOperand N) { SDOperand N0, N1, N2; - if (isa(N.Val)) return true; if (isSetCCEquivalent(N, N0, N1, N2) && N.Val->hasOneUse()) return true; return false; @@ -270,7 +270,7 @@ DEBUG(std::cerr << "\nReplacing "; N->dump(); std::cerr << "\nWith: "; RV.Val->dump(); std::cerr << '\n'); - DAG.ReplaceAllUsesWith(SDOperand(N, 0), RV); + DAG.ReplaceAllUsesWith(N, std::vector(1, RV)); // Push the new node and any users onto the worklist WorkList.push_back(RV.Val); @@ -347,6 +347,11 @@ // fold (add c1, c2) -> c1+c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() + N1C->getValue(), VT); + // canonicalize constant to RHS + if (N0C && !N1C) { + std::swap(N0, N1); + std::swap(N0C, N1C); + } // fold (add x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -426,6 +431,11 @@ if (N0C && N1C) return DAG.getConstant(N0C->getValue() * N1C->getValue(), N->getValueType(0)); + // canonicalize constant to RHS + if (N0C && !N1C) { + std::swap(N0, N1); + std::swap(N0C, N1C); + } // fold (mul x, 0) -> 0 if (N1C && N1C->isNullValue()) return N1; @@ -556,6 +566,11 @@ // fold (and c1, c2) -> c1&c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() & N1C->getValue(), VT); + // canonicalize constant to RHS + if (N0C && !N1C) { + std::swap(N0, N1); + std::swap(N0C, N1C); + } // fold (and x, -1) -> x if (N1C && N1C->isAllOnesValue()) return N0; @@ -593,6 +608,11 @@ if (N0C && N1C) return DAG.getConstant(N0C->getValue() | N1C->getValue(), N->getValueType(0)); + // canonicalize constant to RHS + if (N0C && !N1C) { + std::swap(N0, N1); + std::swap(N0C, N1C); + } // fold (or x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -617,6 +637,11 @@ // fold (xor c1, c2) -> c1^c2 if (N0C && N1C) return DAG.getConstant(N0C->getValue() ^ N1C->getValue(), VT); + // canonicalize constant to RHS + if (N0C && !N1C) { + std::swap(N0, N1); + std::swap(N0C, N1C); + } // fold (xor x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -632,22 +657,28 @@ assert(0 && "Unhandled SetCC Equivalent!"); abort(); } - // fold !(x or y) -> (!x and !y) iff x or y are freely invertible - if (N1C && N1C->isAllOnesValue() && N0.getOpcode() == ISD::OR) { + // fold !(x or y) -> (!x and !y) iff x or y are setcc + if (N1C && N1C->getValue() == 1 && + (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); - if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { + if (isOneUseSetCC(RHS) || isOneUseSetCC(LHS)) { + unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND; LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS - return DAG.getNode(ISD::AND, VT, LHS, RHS); + WorkList.push_back(LHS.Val); WorkList.push_back(RHS.Val); + return DAG.getNode(NewOpcode, VT, LHS, RHS); } } - // fold !(x and y) -> (!x or !y) iff x or y are freely invertible - if (N1C && N1C->isAllOnesValue() && N0.getOpcode() == ISD::AND) { + // fold !(x or y) -> (!x and !y) iff x or y are constants + if (N1C && N1C->isAllOnesValue() && + (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); - if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { + if (isa(RHS) || isa(LHS)) { + unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND; LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS - return DAG.getNode(ISD::OR, VT, LHS, RHS); + WorkList.push_back(LHS.Val); WorkList.push_back(RHS.Val); + return DAG.getNode(NewOpcode, VT, LHS, RHS); } } return SDOperand(); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.187 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.188 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.187 Wed Sep 7 00:37:01 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Sep 7 18:25:52 2005 @@ -1256,7 +1256,6 @@ ConstantSDNode *N2C = dyn_cast(N2.Val); if (N1C) { if (N2C) { - if (!CombinerEnabled) { uint64_t C1 = N1C->getValue(), C2 = N2C->getValue(); switch (Opcode) { case ISD::ADD: return getConstant(C1 + C2, VT); @@ -1284,7 +1283,6 @@ case ISD::SRA : return getConstant(N1C->getSignExtended() >>(int)C2, VT); default: break; } - } } else { // Cannonicalize constant to RHS if commutative if (isCommutativeBinOp(Opcode)) { std::swap(N1C, N2C); @@ -1315,6 +1313,7 @@ if (N2C) { uint64_t C2 = N2C->getValue(); + if (!CombinerEnabled) { switch (Opcode) { case ISD::ADD: if (!C2) return N1; // add X, 0 -> X @@ -1481,6 +1480,7 @@ } break; } + } // Reassociate ((X op C1) op C2) if possible. if (N1.getOpcode() == Opcode && isAssociativeBinOp(Opcode)) @@ -1493,7 +1493,6 @@ ConstantFPSDNode *N2CFP = dyn_cast(N2.Val); if (N1CFP) { if (N2CFP) { - if (!CombinerEnabled) { double C1 = N1CFP->getValue(), C2 = N2CFP->getValue(); switch (Opcode) { case ISD::ADD: return getConstantFP(C1 + C2, VT); @@ -1507,7 +1506,6 @@ break; default: break; } - } } else { // Cannonicalize constant to RHS if commutative if (isCommutativeBinOp(Opcode)) { std::swap(N1CFP, N2CFP); @@ -1515,9 +1513,11 @@ } } + if (!CombinerEnabled) { if (Opcode == ISD::FP_ROUND_INREG) return getNode(ISD::FP_EXTEND, VT, getNode(ISD::FP_ROUND, cast(N2)->getVT(), N1)); + } } // Finally, fold operations that do not require constants. From lattner at cs.uiuc.edu Wed Sep 7 18:44:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 18:44:54 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509072344.SAA30924@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp added (r1.1) DAGISelEmitter.h updated: 1.1 -> 1.2 --- Log message: Initial cut of the dag isel generator. This is still very much a work in progress. It correctly parses instructions and pattern fragments and glues together pattern fragments into instructions. The only code it generates currently is some boilerplate code for things like the EntryNode. --- Diffs of the changes: (+643 -1) DAGISelEmitter.cpp | 475 +++++++++++++++++++++++++++++++++++++++++++++++++++++ DAGISelEmitter.h | 169 ++++++++++++++++++ 2 files changed, 643 insertions(+), 1 deletion(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -c /dev/null llvm/utils/TableGen/DAGISelEmitter.cpp:1.1 *** /dev/null Wed Sep 7 18:44:53 2005 --- llvm/utils/TableGen/DAGISelEmitter.cpp Wed Sep 7 18:44:43 2005 *************** *** 0 **** --- 1,475 ---- + //===- DAGISelEmitter.cpp - Generate an instruction selector --------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This tablegen backend emits a DAG instruction selector. + // + //===----------------------------------------------------------------------===// + + #include "DAGISelEmitter.h" + #include "Record.h" + #include "llvm/ADT/StringExtras.h" + #include "llvm/Support/Debug.h" + #include + using namespace llvm; + + + //===----------------------------------------------------------------------===// + // TreePatternNode implementation + // + + TreePatternNode::~TreePatternNode() { + #if 0 // FIXME: implement refcounted tree nodes! + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + delete getChild(i); + #endif + } + + void TreePatternNode::print(std::ostream &OS) const { + if (isLeaf()) { + OS << *getLeafValue(); + } else { + OS << "(" << getOperator()->getName(); + } + + if (getType() == MVT::Other) + OS << ":Other"; + else if (getType() == MVT::LAST_VALUETYPE) + ;//OS << ":?"; + else + OS << ":" << getType(); + + if (!isLeaf()) { + if (getNumChildren() != 0) { + OS << " "; + getChild(0)->print(OS); + for (unsigned i = 1, e = getNumChildren(); i != e; ++i) { + OS << ", "; + getChild(i)->print(OS); + } + } + OS << ")"; + } + + if (!PredicateFn.empty()) + OS << "<<" << PredicateFn << ">>"; + if (!getName().empty()) + OS << ":$" << getName(); + + } + void TreePatternNode::dump() const { + print(std::cerr); + } + + /// clone - Make a copy of this tree and all of its children. + /// + TreePatternNode *TreePatternNode::clone() const { + TreePatternNode *New; + if (isLeaf()) { + New = new TreePatternNode(getLeafValue()); + } else { + std::vector CChildren; + CChildren.reserve(Children.size()); + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + CChildren.push_back(getChild(i)->clone()); + New = new TreePatternNode(getOperator(), CChildren); + } + New->setName(getName()); + New->setType(getType()); + New->setPredicateFn(getPredicateFn()); + return New; + } + + void TreePatternNode:: + SubstituteFormalArguments(std::map &ArgMap) { + if (isLeaf()) return; + + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { + TreePatternNode *Child = getChild(i); + if (Child->isLeaf()) { + Init *Val = Child->getLeafValue(); + if (dynamic_cast(Val) && + static_cast(Val)->getDef()->getName() == "node") { + // We found a use of a formal argument, replace it with its value. + Child = ArgMap[Child->getName()]; + assert(Child && "Couldn't find formal argument!"); + setChild(i, Child); + } + } else { + getChild(i)->SubstituteFormalArguments(ArgMap); + } + } + } + + + /// InlinePatternFragments - If this pattern refers to any pattern + /// fragments, inline them into place, giving us a pattern without any + /// PatFrag references. + TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { + if (isLeaf()) return this; // nothing to do. + Record *Op = getOperator(); + + if (!Op->isSubClassOf("PatFrag")) { + // Just recursively inline children nodes. + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + setChild(i, getChild(i)->InlinePatternFragments(TP)); + return this; + } + + // Otherwise, we found a reference to a fragment. First, look up its + // TreePattern record. + TreePattern *Frag = TP.getDAGISelEmitter().getPatternFragment(Op); + + // Verify that we are passing the right number of operands. + if (Frag->getNumArgs() != Children.size()) + TP.error("'" + Op->getName() + "' fragment requires " + + utostr(Frag->getNumArgs()) + " operands!"); + + TreePatternNode *FragTree = Frag->getTrees()[0]->clone(); + + // Resolve formal arguments to their actual value. + if (Frag->getNumArgs()) { + // Compute the map of formal to actual arguments. + std::map ArgMap; + for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i) + ArgMap[Frag->getArgName(i)] = getChild(i)->InlinePatternFragments(TP); + + FragTree->SubstituteFormalArguments(ArgMap); + } + + // Get a new copy of this fragment to stitch into here. + //delete this; // FIXME: implement refcounting! + return FragTree; + } + + //===----------------------------------------------------------------------===// + // TreePattern implementation + // + + TreePattern::TreePattern(PatternType pty, Record *TheRec, + const std::vector &RawPat, + DAGISelEmitter &ise) + : PTy(pty), TheRecord(TheRec), ISE(ise) { + + for (unsigned i = 0, e = RawPat.size(); i != e; ++i) + Trees.push_back(ParseTreePattern(RawPat[i])); + + // Sanity checks and cleanup. + switch (PTy) { + case PatFrag: { + assert(Trees.size() == 1 && "How can we have more than one pattern here?"); + + // Validate arguments list, convert it to map, to discard duplicates. + std::set OperandsMap(Args.begin(), Args.end()); + + if (OperandsMap.count("")) + error("Cannot have unnamed 'node' values in pattern fragment!"); + + // Parse the operands list. + DagInit *OpsList = TheRec->getValueAsDag("Operands"); + if (OpsList->getNodeType()->getName() != "ops") + error("Operands list should start with '(ops ... '!"); + + // Copy over the arguments. + Args.clear(); + for (unsigned i = 0, e = OpsList->getNumArgs(); i != e; ++i) { + if (!dynamic_cast(OpsList->getArg(i)) || + static_cast(OpsList->getArg(i))-> + getDef()->getName() != "node") + error("Operands list should all be 'node' values."); + if (OpsList->getArgName(i).empty()) + error("Operands list should have names for each operand!"); + if (!OperandsMap.count(OpsList->getArgName(i))) + error("'" + OpsList->getArgName(i) + + "' does not occur in pattern or was multiply specified!"); + OperandsMap.erase(OpsList->getArgName(i)); + Args.push_back(OpsList->getArgName(i)); + } + + if (!OperandsMap.empty()) + error("Operands list does not contain an entry for operand '" + + *OperandsMap.begin() + "'!"); + + break; + } + default: + if (!Args.empty()) + error("Only pattern fragments can have operands (use 'node' values)!"); + break; + } + } + + void TreePattern::error(const std::string &Msg) const { + std::string M = "In "; + switch (PTy) { + case PatFrag: M += "patfrag "; break; + case Instruction: M += "instruction "; break; + } + throw M + TheRecord->getName() + ": " + Msg; + } + + /// getIntrinsicType - Check to see if the specified record has an intrinsic + /// type which should be applied to it. This infer the type of register + /// references from the register file information, for example. + /// + MVT::ValueType TreePattern::getIntrinsicType(Record *R) const { + // Check to see if this is a register or a register class... + if (R->isSubClassOf("RegisterClass")) + return getValueType(R->getValueAsDef("RegType")); + else if (R->isSubClassOf("PatFrag")) { + //return ISE.ReadNonterminal(R)->getTree()->getType(); + return MVT::LAST_VALUETYPE; + } else if (R->isSubClassOf("Register")) { + assert(0 && "Explicit registers not handled here yet!\n"); + return MVT::LAST_VALUETYPE; + } else if (R->isSubClassOf("ValueType")) { + // Using a VTSDNode. + return MVT::Other; + } else if (R->getName() == "node") { + // Placeholder. + return MVT::LAST_VALUETYPE; + } + + error("Unknown value used: " + R->getName()); + return MVT::Other; + } + + TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) { + Record *Operator = Dag->getNodeType(); + + if (Operator->isSubClassOf("ValueType")) { + // If the operator is a ValueType, then this must be "type cast" of a leaf + // node. + if (Dag->getNumArgs() != 1) + error("Type cast only valid for a leaf node!"); + + Init *Arg = Dag->getArg(0); + TreePatternNode *New; + if (DefInit *DI = dynamic_cast(Arg)) { + New = new TreePatternNode(DI); + // If it's a regclass or something else known, set the type. + New->setType(getIntrinsicType(DI->getDef())); + } else if (DagInit *DI = dynamic_cast(Arg)) { + New = ParseTreePattern(DI); + } else { + Arg->dump(); + error("Unknown leaf value for tree pattern!"); + return 0; + } + + // Apply the type cast... + assert(0 && "unimp yet"); + //New->updateNodeType(getValueType(Operator), TheRecord->getName()); + return New; + } + + // Verify that this is something that makes sense for an operator. + if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") && + Operator->getName() != "set") + error("Unrecognized node '" + Operator->getName() + "'!"); + + std::vector Children; + + for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { + Init *Arg = Dag->getArg(i); + if (DagInit *DI = dynamic_cast(Arg)) { + Children.push_back(ParseTreePattern(DI)); + Children.back()->setName(Dag->getArgName(i)); + } else if (DefInit *DefI = dynamic_cast(Arg)) { + Record *R = DefI->getDef(); + // Direct reference to a leaf DagNode or PatFrag? Turn it into a + // TreePatternNode if its own. + if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) { + Dag->setArg(i, new DagInit(R, + std::vector >())); + --i; // Revisit this node... + } else { + TreePatternNode *Node = new TreePatternNode(DefI); + Node->setName(Dag->getArgName(i)); + Children.push_back(Node); + + // If it's a regclass or something else known, set the type. + Node->setType(getIntrinsicType(R)); + + // Input argument? + if (R->getName() == "node") { + if (Dag->getArgName(i).empty()) + error("'node' argument requires a name to match with operand list"); + Args.push_back(Dag->getArgName(i)); + } + } + } else { + Arg->dump(); + error("Unknown leaf value for tree pattern!"); + } + } + + return new TreePatternNode(Operator, Children); + } + + void TreePattern::print(std::ostream &OS) const { + switch (getPatternType()) { + case TreePattern::PatFrag: OS << "PatFrag pattern "; break; + case TreePattern::Instruction: OS << "Inst pattern "; break; + } + + OS << getRecord()->getName(); + if (!Args.empty()) { + OS << "(" << Args[0]; + for (unsigned i = 1, e = Args.size(); i != e; ++i) + OS << ", " << Args[i]; + OS << ")"; + } + OS << ": "; + + if (Trees.size() > 1) + OS << "[\n"; + for (unsigned i = 0, e = Trees.size(); i != e; ++i) { + OS << "\t"; + Trees[i]->print(OS); + OS << "\n"; + } + + if (Trees.size() > 1) + OS << "]\n"; + } + + void TreePattern::dump() const { print(std::cerr); } + + + + //===----------------------------------------------------------------------===// + // DAGISelEmitter implementation + // + + /// ParseAndResolvePatternFragments - Parse all of the PatFrag definitions in + /// the .td file, building up the PatternFragments map. After we've collected + /// them all, inline fragments together as necessary, so that there are no + /// references left inside a pattern fragment to a pattern fragment. + /// + /// This also emits all of the predicate functions to the output file. + /// + void DAGISelEmitter::ParseAndResolvePatternFragments(std::ostream &OS) { + std::vector Fragments = Records.getAllDerivedDefinitions("PatFrag"); + + // First step, parse all of the fragments and emit predicate functions. + OS << "\n// Predicate functions.\n"; + for (unsigned i = 0, e = Fragments.size(); i != e; ++i) { + std::vector Trees; + Trees.push_back(Fragments[i]->getValueAsDag("Fragment")); + TreePattern *P = new TreePattern(TreePattern::PatFrag, Fragments[i], + Trees, *this); + PatternFragments[Fragments[i]] = P; + + // If there is a code init for this fragment, emit the predicate code and + // keep track of the fact that this fragment uses it. + CodeInit *CI = + dynamic_cast(Fragments[i]->getValueInit("Predicate")); + if (!CI->getValue().empty()) { + assert(!P->getTrees()[0]->isLeaf() && "Can't be a leaf!"); + std::string ClassName = + P->getTrees()[0]->getOperator()->getValueAsString("SDClass"); + const char *C2 = ClassName == "SDNode" ? "N" : "inN"; + + OS << "static inline bool Predicate_" << Fragments[i]->getName() + << "(SDNode *" << C2 << ") {\n"; + if (ClassName != "SDNode") + OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n"; + OS << CI->getValue() << "\n}\n"; + P->getTrees()[0]->setPredicateFn("Predicate_"+Fragments[i]->getName()); + } + } + + OS << "\n\n"; + + // Now that we've parsed all of the tree fragments, do a closure on them so + // that there are not references to PatFrags left inside of them. + for (std::map::iterator I = PatternFragments.begin(), + E = PatternFragments.end(); I != E; ++I) { + I->second->InlinePatternFragments(); + // If debugging, print out the pattern fragment result. + DEBUG(I->second->dump()); + } + } + + /// ParseAndResolveInstructions - Parse all of the instructions, inlining and + /// resolving any fragments involved. This populates the Instructions list with + /// fully resolved instructions. + void DAGISelEmitter::ParseAndResolveInstructions() { + std::vector Instrs = Records.getAllDerivedDefinitions("Instruction"); + + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { + if (!dynamic_cast(Instrs[i]->getValueInit("Pattern"))) + continue; // no pattern yet, ignore it. + + ListInit *LI = Instrs[i]->getValueAsListInit("Pattern"); + if (LI->getSize() == 0) continue; // no pattern. + + std::vector Trees; + for (unsigned j = 0, e = LI->getSize(); j != e; ++j) + Trees.push_back((DagInit*)LI->getElement(j)); + + // Parse the instruction. + Instructions.push_back(new TreePattern(TreePattern::Instruction, Instrs[i], + Trees, *this)); + // Inline pattern fragments into it. + Instructions.back()->InlinePatternFragments(); + + DEBUG(std::cerr << Instrs[i]->getName() << ": "); + DEBUG(Instructions.back()->dump()); + } + } + + void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { + // Emit boilerplate. + OS << "// The main instruction selector code.\n" + << "SDOperand " << Target.getName() + << "DAGToDAGISel::SelectCode(SDOperand Op) {\n" + << " SDNode *N = Op.Val;\n" + << " if (N->getOpcode() >= ISD::BUILTIN_OP_END &&\n" + << " N->getOpcode() < PPCISD::FIRST_NUMBER)\n" + << " return Op; // Already selected.\n\n" + << " switch (N->getOpcode()) {\n" + << " default: break;\n" + << " case ISD::EntryToken: // These leaves remain the same.\n" + << " return Op;\n" + << " case ISD::AssertSext:\n" + << " case ISD::AssertZext:\n" + << " return Select(N->getOperand(0));\n"; + + + + OS << " } // end of big switch.\n\n" + << " std::cerr << \"Cannot yet select: \";\n" + << " N->dump();\n" + << " std::cerr << '\\n';\n" + << " abort();\n" + << "}\n"; + } + + + void DAGISelEmitter::run(std::ostream &OS) { + EmitSourceFileHeader("DAG Instruction Selector for the " + Target.getName() + + " target", OS); + + ParseAndResolvePatternFragments(OS); + ParseAndResolveInstructions(); + + // TODO: convert some instructions to expanders if needed or something. + + EmitInstructionSelector(OS); + + for (std::map::iterator I = PatternFragments.begin(), + E = PatternFragments.end(); I != E; ++I) + delete I->second; + PatternFragments.clear(); + + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) + delete Instructions[i]; + Instructions.clear(); + } Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.1 llvm/utils/TableGen/DAGISelEmitter.h:1.2 --- llvm/utils/TableGen/DAGISelEmitter.h:1.1 Fri Sep 2 20:14:03 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Sep 7 18:44:43 2005 @@ -18,7 +18,162 @@ #include "CodeGenTarget.h" namespace llvm { + class Record; + class Init; + class DagInit; + class TreePattern; + class DAGISelEmitter; + /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped + /// patterns), and as such should be ref counted. We currently just leak all + /// TreePatternNode objects! + class TreePatternNode { + /// The inferred type for this node, or MVT::LAST_VALUETYPE if it hasn't + /// been determined yet. + MVT::ValueType Ty; + + /// Operator - The Record for the operator if this is an interior node (not + /// a leaf). + Record *Operator; + + /// Val - The init value (e.g. the "GPRC" record, or "7") for a leaf. + /// + Init *Val; + + /// Name - The name given to this node with the :$foo notation. + /// + std::string Name; + + /// PredicateFn - The predicate function to execute on this node to check + /// for a match. If this string is empty, no predicate is involved. + std::string PredicateFn; + + std::vector Children; + public: + TreePatternNode(Record *Op, const std::vector &Ch) + : Ty(MVT::LAST_VALUETYPE), Operator(Op), Val(0), Children(Ch) {} + TreePatternNode(Init *val) // leaf ctor + : Ty(MVT::LAST_VALUETYPE), Operator(0), Val(val) {} + ~TreePatternNode(); + + const std::string &getName() const { return Name; } + void setName(const std::string &N) { Name = N; } + + bool isLeaf() const { return Val != 0; } + MVT::ValueType getType() const { return Ty; } + void setType(MVT::ValueType VT) { Ty = VT; } + + Init *getLeafValue() const { assert(isLeaf()); return Val; } + Record *getOperator() const { assert(!isLeaf()); return Operator; } + + unsigned getNumChildren() const { return Children.size(); } + TreePatternNode *getChild(unsigned N) const { return Children[N]; } + void setChild(unsigned i, TreePatternNode *N) { + Children[i] = N; + } + + const std::string &getPredicateFn() const { return PredicateFn; } + void setPredicateFn(const std::string &Fn) { PredicateFn = Fn; } + + void print(std::ostream &OS) const; + void dump() const; + + public: // Higher level manipulation routines. + + /// clone - Return a new copy of this tree. + /// + TreePatternNode *clone() const; + + void SubstituteFormalArguments(std::map &ArgMap); + + /// InlinePatternFragments - If this pattern refers to any pattern + /// fragments, inline them into place, giving us a pattern without any + /// PatFrag references. + TreePatternNode *InlinePatternFragments(TreePattern &TP); + + }; + + + /// TreePattern - Represent a pattern of one form or another. Currently, two + /// types of patterns are possible: Instructions and PatFrags. + /// + class TreePattern { + public: + enum PatternType { + PatFrag, Instruction + }; + private: + /// PTy - The type of pattern this is. + /// + PatternType PTy; + + /// Trees - The list of pattern trees which corresponds to this pattern. + /// Note that PatFrag's only have a single tree. + /// + std::vector Trees; + + /// TheRecord - The actual TableGen record corresponding to this pattern. + /// + Record *TheRecord; + + /// Args - This is a list of all of the arguments to this pattern (for + /// PatFrag patterns), which are the 'node' markers in this pattern. + std::vector Args; + + /// ISE - the DAG isel emitter coordinating this madness. + /// + DAGISelEmitter &ISE; + public: + + /// TreePattern constructor - Parse the specified DagInits into the + /// current record. + TreePattern(PatternType pty, Record *TheRec, + const std::vector &RawPat, DAGISelEmitter &ise); + + /// getPatternType - Return what flavor of Record this pattern originated from + /// + PatternType getPatternType() const { return PTy; } + + /// getTrees - Return the tree patterns which corresponds to this pattern. + /// + const std::vector &getTrees() const { return Trees; } + + /// getRecord - Return the actual TableGen record corresponding to this + /// pattern. + /// + Record *getRecord() const { return TheRecord; } + + unsigned getNumArgs() const { return Args.size(); } + const std::string &getArgName(unsigned i) const { + assert(i < Args.size() && "Argument reference out of range!"); + return Args[i]; + } + + DAGISelEmitter &getDAGISelEmitter() const { return ISE; } + + /// InlinePatternFragments - If this pattern refers to any pattern + /// fragments, inline them into place, giving us a pattern without any + /// PatFrag references. + void InlinePatternFragments() { + for (unsigned i = 0, e = Trees.size(); i != e; ++i) + Trees[i] = Trees[i]->InlinePatternFragments(*this); + } + + /// error - Throw an exception, prefixing it with information about this + /// pattern. + void error(const std::string &Msg) const; + + void print(std::ostream &OS) const; + void dump() const; + + private: + MVT::ValueType getIntrinsicType(Record *R) const; + TreePatternNode *ParseTreePattern(DagInit *DI); + }; + + + /// InstrSelectorEmitter - The top-level class which coordinates construction /// and emission of the instruction selector. /// @@ -26,11 +181,23 @@ RecordKeeper &Records; CodeGenTarget Target; + std::map PatternFragments; + std::vector Instructions; public: DAGISelEmitter(RecordKeeper &R) : Records(R) {} // run - Output the isel, returning true on failure. - void run(std::ostream &OS) {} + void run(std::ostream &OS); + + TreePattern *getPatternFragment(Record *R) const { + assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); + return PatternFragments.find(R)->second; + } + +private: + void ParseAndResolvePatternFragments(std::ostream &OS); + void ParseAndResolveInstructions(); + void EmitInstructionSelector(std::ostream &OS); }; } // End llvm namespace From lattner at cs.uiuc.edu Wed Sep 7 18:45:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 18:45:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509072345.SAA30967@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.73 -> 1.74 --- Log message: Remove some cases handled by the generated portion of the isel --- Diffs of the changes: (+3 -13) PPC32ISelDAGToDAG.cpp | 16 +++------------- 1 files changed, 3 insertions(+), 13 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.73 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.74 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.73 Tue Sep 6 17:03:27 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Sep 7 18:45:15 2005 @@ -62,6 +62,7 @@ // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. SDOperand Select(SDOperand Op); + SDOperand SelectCode(SDOperand Op); SDNode *SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS, unsigned OCHi, unsigned OCLo, @@ -636,16 +637,7 @@ return Op; // Already selected. switch (N->getOpcode()) { - default: - std::cerr << "Cannot yet select: "; - N->dump(); - std::cerr << "\n"; - abort(); - case ISD::EntryToken: // These leaves remain the same. - return Op; - case ISD::AssertSext: - case ISD::AssertZext: - return Select(N->getOperand(0)); + default: break; case ISD::TokenFactor: { SDOperand New; if (N->getNumOperands() == 2) { @@ -1598,9 +1590,7 @@ } } - assert(0 && "Unreachable!"); - abort(); - return SDOperand(N, Op.ResNo); + return SelectCode(Op); } From lattner at cs.uiuc.edu Wed Sep 7 18:47:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 18:47:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/.cvsignore Message-ID: <200509072347.SAA31133@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: .cvsignore added (r1.1) --- Log message: ignore generated files --- Diffs of the changes: (+1 -0) .cvsignore | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/IA64/.cvsignore diff -c /dev/null llvm/lib/Target/IA64/.cvsignore:1.1 *** /dev/null Wed Sep 7 18:47:09 2005 --- llvm/lib/Target/IA64/.cvsignore Wed Sep 7 18:46:59 2005 *************** *** 0 **** --- 1 ---- + *.inc From lattner at cs.uiuc.edu Wed Sep 7 18:47:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 18:47:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/.cvsignore Message-ID: <200509072347.SAA31137@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: .cvsignore added (r1.1) --- Log message: ignore generated files --- Diffs of the changes: (+1 -0) .cvsignore | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/SparcV8/.cvsignore diff -c /dev/null llvm/lib/Target/SparcV8/.cvsignore:1.1 *** /dev/null Wed Sep 7 18:47:09 2005 --- llvm/lib/Target/SparcV8/.cvsignore Wed Sep 7 18:46:59 2005 *************** *** 0 **** --- 1 ---- + *.inc From lattner at cs.uiuc.edu Wed Sep 7 18:47:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 18:47:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/.cvsignore Message-ID: <200509072347.SAA31218@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: .cvsignore added (r1.1) --- Log message: ignore generated files --- Diffs of the changes: (+1 -0) .cvsignore | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Alpha/.cvsignore diff -c /dev/null llvm/lib/Target/Alpha/.cvsignore:1.1 *** /dev/null Wed Sep 7 18:47:54 2005 --- llvm/lib/Target/Alpha/.cvsignore Wed Sep 7 18:47:44 2005 *************** *** 0 **** --- 1 ---- + *.inc From lattner at cs.uiuc.edu Wed Sep 7 18:54:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 18:54:00 -0500 Subject: [llvm-commits] CVS: llvm/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200509072354.SAA31346@zion.cs.uiuc.edu> Changes in directory llvm/Xcode/LLVM.xcodeproj: project.pbxproj updated: 1.7 -> 1.8 --- Log message: Add tblgen fpcmp and the nightly tester to the utils folder --- Diffs of the changes: (+71 -0) project.pbxproj | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 71 insertions(+) Index: llvm/Xcode/LLVM.xcodeproj/project.pbxproj diff -u llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.7 llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.8 --- llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.7 Thu Sep 1 16:38:20 2005 +++ llvm/Xcode/LLVM.xcodeproj/project.pbxproj Wed Sep 7 18:53:49 2005 @@ -839,6 +839,33 @@ DE66F41E08ABF37000323D32 /* ModuleMaker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleMaker.cpp; path = ModuleMaker/ModuleMaker.cpp; sourceTree = ""; }; DE66F42608ABF37000323D32 /* ParallelJIT.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParallelJIT.cpp; path = ParallelJIT/ParallelJIT.cpp; sourceTree = ""; }; DE694D9F08B51E0C0039C106 /* ScheduleDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ScheduleDAG.cpp; sourceTree = ""; }; + DE81704008CFB44D0093BDEF /* fpcmp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = fpcmp.cpp; path = fpcmp/fpcmp.cpp; sourceTree = ""; }; + DE81704F08CFB44D0093BDEF /* NightlyTest.gnuplot */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = NightlyTest.gnuplot; sourceTree = ""; }; + DE81705008CFB44D0093BDEF /* NightlyTest.pl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = NightlyTest.pl; sourceTree = ""; }; + DE81705108CFB44D0093BDEF /* NightlyTestTemplate.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; path = NightlyTestTemplate.html; sourceTree = ""; }; + DE81705908CFB44D0093BDEF /* AsmWriterEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AsmWriterEmitter.cpp; sourceTree = ""; }; + DE81705A08CFB44D0093BDEF /* AsmWriterEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AsmWriterEmitter.h; sourceTree = ""; }; + DE81705B08CFB44D0093BDEF /* CodeEmitterGen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CodeEmitterGen.cpp; sourceTree = ""; }; + DE81705C08CFB44D0093BDEF /* CodeEmitterGen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeEmitterGen.h; sourceTree = ""; }; + DE81705D08CFB44D0093BDEF /* CodeGenInstruction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeGenInstruction.h; sourceTree = ""; }; + DE81705E08CFB44D0093BDEF /* CodeGenRegisters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeGenRegisters.h; sourceTree = ""; }; + DE81705F08CFB44D0093BDEF /* CodeGenTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenTarget.cpp; sourceTree = ""; }; + DE81706008CFB44D0093BDEF /* CodeGenTarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeGenTarget.h; sourceTree = ""; }; + DE81706708CFB44D0093BDEF /* DAGISelEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DAGISelEmitter.cpp; sourceTree = ""; }; + DE81706808CFB44D0093BDEF /* DAGISelEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DAGISelEmitter.h; sourceTree = ""; }; + DE81708408CFB44D0093BDEF /* FileLexer.l */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.lex; path = FileLexer.l; sourceTree = ""; }; + DE81708808CFB44D0093BDEF /* FileParser.y */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.yacc; path = FileParser.y; sourceTree = ""; }; + DE81708908CFB44D0093BDEF /* InstrInfoEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstrInfoEmitter.cpp; sourceTree = ""; }; + DE81708A08CFB44D0093BDEF /* InstrInfoEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstrInfoEmitter.h; sourceTree = ""; }; + DE81708B08CFB44D0093BDEF /* InstrSelectorEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstrSelectorEmitter.cpp; sourceTree = ""; }; + DE81708C08CFB44D0093BDEF /* InstrSelectorEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstrSelectorEmitter.h; sourceTree = ""; }; + DE81708E08CFB44D0093BDEF /* Record.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Record.cpp; sourceTree = ""; }; + DE81708F08CFB44D0093BDEF /* Record.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Record.h; sourceTree = ""; }; + DE81709008CFB44D0093BDEF /* RegisterInfoEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterInfoEmitter.cpp; sourceTree = ""; }; + DE81709108CFB44D0093BDEF /* RegisterInfoEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RegisterInfoEmitter.h; sourceTree = ""; }; + DE8170AA08CFB44D0093BDEF /* TableGen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGen.cpp; sourceTree = ""; }; + DE8170AB08CFB44D0093BDEF /* TableGenBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGenBackend.cpp; sourceTree = ""; }; + DE8170AC08CFB44D0093BDEF /* TableGenBackend.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TableGenBackend.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ @@ -859,6 +886,7 @@ DE66F0E108ABEFB300323D32 /* lib/Transforms */, DE66EC7508ABE8EF00323D32 /* lib/VMCore */, DE66F2BD08ABF14400323D32 /* tools */, + DE816FAC08CFB44C0093BDEF /* utils */, DE66F38D08ABF35C00323D32 /* docs */, DE66F3FD08ABF37000323D32 /* examples */, DE66F38C08ABF35300323D32 /* CREDITS.TXT */, @@ -2207,6 +2235,49 @@ path = ../examples; sourceTree = SOURCE_ROOT; }; + DE816FAC08CFB44C0093BDEF /* utils */ = { + isa = PBXGroup; + children = ( + DE81705708CFB44D0093BDEF /* TableGen */, + DE81704008CFB44D0093BDEF /* fpcmp.cpp */, + DE81704F08CFB44D0093BDEF /* NightlyTest.gnuplot */, + DE81705008CFB44D0093BDEF /* NightlyTest.pl */, + DE81705108CFB44D0093BDEF /* NightlyTestTemplate.html */, + ); + name = utils; + path = ../utils; + sourceTree = SOURCE_ROOT; + }; + DE81705708CFB44D0093BDEF /* TableGen */ = { + isa = PBXGroup; + children = ( + DE81705908CFB44D0093BDEF /* AsmWriterEmitter.cpp */, + DE81705A08CFB44D0093BDEF /* AsmWriterEmitter.h */, + DE81705B08CFB44D0093BDEF /* CodeEmitterGen.cpp */, + DE81705C08CFB44D0093BDEF /* CodeEmitterGen.h */, + DE81705D08CFB44D0093BDEF /* CodeGenInstruction.h */, + DE81705E08CFB44D0093BDEF /* CodeGenRegisters.h */, + DE81705F08CFB44D0093BDEF /* CodeGenTarget.cpp */, + DE81706008CFB44D0093BDEF /* CodeGenTarget.h */, + DE81706708CFB44D0093BDEF /* DAGISelEmitter.cpp */, + DE81706808CFB44D0093BDEF /* DAGISelEmitter.h */, + DE81708408CFB44D0093BDEF /* FileLexer.l */, + DE81708808CFB44D0093BDEF /* FileParser.y */, + DE81708908CFB44D0093BDEF /* InstrInfoEmitter.cpp */, + DE81708A08CFB44D0093BDEF /* InstrInfoEmitter.h */, + DE81708B08CFB44D0093BDEF /* InstrSelectorEmitter.cpp */, + DE81708C08CFB44D0093BDEF /* InstrSelectorEmitter.h */, + DE81708E08CFB44D0093BDEF /* Record.cpp */, + DE81708F08CFB44D0093BDEF /* Record.h */, + DE81709008CFB44D0093BDEF /* RegisterInfoEmitter.cpp */, + DE81709108CFB44D0093BDEF /* RegisterInfoEmitter.h */, + DE8170AA08CFB44D0093BDEF /* TableGen.cpp */, + DE8170AB08CFB44D0093BDEF /* TableGenBackend.cpp */, + DE8170AC08CFB44D0093BDEF /* TableGenBackend.h */, + ); + path = TableGen; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXLegacyTarget section */ From lattner at cs.uiuc.edu Wed Sep 7 18:57:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 7 Sep 2005 18:57:11 -0500 Subject: [llvm-commits] CVS: llvm/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200509072357.SAA31416@zion.cs.uiuc.edu> Changes in directory llvm/Xcode/LLVM.xcodeproj: project.pbxproj updated: 1.8 -> 1.9 --- Log message: add some missing PPC backend files --- Diffs of the changes: (+6 -0) project.pbxproj | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/Xcode/LLVM.xcodeproj/project.pbxproj diff -u llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.8 llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.9 --- llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.8 Wed Sep 7 18:53:49 2005 +++ llvm/Xcode/LLVM.xcodeproj/project.pbxproj Wed Sep 7 18:57:00 2005 @@ -866,6 +866,9 @@ DE8170AA08CFB44D0093BDEF /* TableGen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGen.cpp; sourceTree = ""; }; DE8170AB08CFB44D0093BDEF /* TableGenBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGenBackend.cpp; sourceTree = ""; }; DE8170AC08CFB44D0093BDEF /* TableGenBackend.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TableGenBackend.h; sourceTree = ""; }; + DE8170C108CFB59B0093BDEF /* PPC32ISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32ISelDAGToDAG.cpp; sourceTree = ""; }; + DE8170C408CFB5B20093BDEF /* PPC32ISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32ISelLowering.cpp; sourceTree = ""; }; + DE8170C508CFB5B20093BDEF /* PPC32ISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPC32ISelLowering.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ @@ -1373,6 +1376,9 @@ DE66EF5208ABEE5F00323D32 /* PPC32CodeEmitter.cpp */, DE66EF5708ABEE5F00323D32 /* PPC32InstrInfo.cpp */, DE66EF5808ABEE5F00323D32 /* PPC32InstrInfo.h */, + DE8170C108CFB59B0093BDEF /* PPC32ISelDAGToDAG.cpp */, + DE8170C408CFB5B20093BDEF /* PPC32ISelLowering.cpp */, + DE8170C508CFB5B20093BDEF /* PPC32ISelLowering.h */, DE66EF5908ABEE5F00323D32 /* PPC32ISelPattern.cpp */, DE66EF5B08ABEE5F00323D32 /* PPC32JITInfo.cpp */, DE66EF5C08ABEE5F00323D32 /* PPC32JITInfo.h */, From lattner at cs.uiuc.edu Thu Sep 8 12:02:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 12:02:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td PowerPCInstrInfo.td Message-ID: <200509081702.MAA23184@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrFormats.td updated: 1.47 -> 1.48 PowerPCInstrInfo.td updated: 1.90 -> 1.91 --- Log message: Add patterns for some new instructions, allowing the use of the ineg fragment. --- Diffs of the changes: (+10 -10) PowerPCInstrFormats.td | 4 ++-- PowerPCInstrInfo.td | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.47 llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.48 --- llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.47 Fri Sep 2 17:35:53 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrFormats.td Thu Sep 8 12:01:54 2005 @@ -449,8 +449,8 @@ } class XOForm_3 opcode, bits<9> xo, bit oe, - dag OL, string asmstr> - : XOForm_1 { + dag OL, string asmstr, list pattern> + : XOForm_1 { let RB = 0; } Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.90 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.91 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.90 Fri Sep 2 20:28:40 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 8 12:01:54 2005 @@ -60,10 +60,6 @@ def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; - - - - class isPPC64 { bit PPC64 = 1; } class isVMX { bit VMX = 1; } class isDOT { @@ -476,13 +472,17 @@ "subfe $rT, $rA, $rB", []>; def ADDME : XOForm_3<31, 234, 0, (ops GPRC:$rT, GPRC:$rA), - "addme $rT, $rA">; + "addme $rT, $rA", + []>; def ADDZE : XOForm_3<31, 202, 0, (ops GPRC:$rT, GPRC:$rA), - "addze $rT, $rA">; + "addze $rT, $rA", + []>; def NEG : XOForm_3<31, 104, 0, (ops GPRC:$rT, GPRC:$rA), - "neg $rT, $rA">; + "neg $rT, $rA", + [(set GPRC:$rT, (ineg GPRC:$rA))]>; def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA), - "subfze $rT, $rA">; + "subfze $rT, $rA", + []>; // A-Form instructions. Most of the instructions executed in the FPU are of // this type. From lattner at cs.uiuc.edu Thu Sep 8 12:33:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 12:33:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td PowerPCInstrInfo.td Message-ID: <200509081733.MAA25191@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrFormats.td updated: 1.48 -> 1.49 PowerPCInstrInfo.td updated: 1.91 -> 1.92 --- Log message: add patterns to the addi/addis/mulli etc instructions. Define predicates for matching signed 16-bit and shifted 16-bit ppc immediates --- Diffs of the changes: (+52 -16) PowerPCInstrFormats.td | 15 +++++++++---- PowerPCInstrInfo.td | 53 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 16 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.48 llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.49 --- llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.48 Thu Sep 8 12:01:54 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrFormats.td Thu Sep 8 12:33:10 2005 @@ -81,7 +81,9 @@ } // 1.7.4 D-Form -class DForm_base opcode, dag OL, string asmstr> : I{ +class DForm_base opcode, dag OL, string asmstr, list pattern> + : I { + let Pattern = pattern; bits<5> A; bits<5> B; bits<16> C; @@ -91,7 +93,8 @@ let Inst{16-31} = C; } -class DForm_1 opcode, dag OL, string asmstr> : I { +class DForm_1 opcode, dag OL, string asmstr> + : I { bits<5> A; bits<16> C; bits<5> B; @@ -101,14 +104,16 @@ let Inst{16-31} = C; } -class DForm_2 opcode, dag OL, string asmstr> - : DForm_base; +class DForm_2 opcode, dag OL, string asmstr, list pattern> + : DForm_base; -class DForm_2_r0 opcode, dag OL, string asmstr> +class DForm_2_r0 opcode, dag OL, string asmstr, list pattern> : I { bits<5> A; bits<16> B; + let Pattern = pattern; + let Inst{6-10} = A; let Inst{11-15} = 0; let Inst{16-31} = B; Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.91 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.92 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.91 Thu Sep 8 12:01:54 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 8 12:33:10 2005 @@ -40,12 +40,17 @@ /// PatFrag - Represents a pattern fragment. This can match something on the /// DAG, frame a single node to multiply nested other fragments. /// -class PatFrag { +class PatFrag { dag Operands = ops; dag Fragment = frag; code Predicate = pred; + code OperandTransform = xform; } -class PatLeaf : PatFrag<(ops), frag, pred>; + +// PatLeaf's are pattern fragments that have no operands. This is just a helper +// to define immediates and other common things concisely. +class PatLeaf + : PatFrag<(ops), frag, pred, xform>; // Leaf fragments. @@ -60,6 +65,23 @@ def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; +// PowerPC-Specific predicates. + +def immSExt16 : PatLeaf<(imm), [{ + // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended + // field. Used by instructions like 'addi'. + return (int)N->getValue() == (short)N->getValue(); +}]>; +def imm16Shifted : PatLeaf<(imm), [{ + // imm16Shifted predicate - True if only bits in the top 16-bits of the + // immediate are set. Used by instructions like 'addis'. + return ((unsigned)N->getValue() & 0xFFFF0000U) == (unsigned)N->getValue(); +}], [{ + // Transformation predicate: shift the immediate value down into the low bits. + return getI32Imm((unsigned)N->getValue() >> 16); +}]>; + + class isPPC64 { bit PPC64 = 1; } class isVMX { bit VMX = 1; } class isDOT { @@ -177,23 +199,32 @@ "lwzu $rD, $disp($rA)">; } def ADDI : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "addi $rD, $rA, $imm">; + "addi $rD, $rA, $imm", + [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>; def ADDIC : DForm_2<12, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "addic $rD, $rA, $imm">; + "addic $rD, $rA, $imm", + []>; def ADDICo : DForm_2<13, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "addic. $rD, $rA, $imm">; + "addic. $rD, $rA, $imm", + []>; def ADDIS : DForm_2<15, (ops GPRC:$rD, GPRC:$rA, symbolHi:$imm), - "addis $rD, $rA, $imm">; + "addis $rD, $rA, $imm", + [(set GPRC:$rD, (add GPRC:$rA, imm16Shifted:$imm))]>; def LA : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, symbolLo:$sym), - "la $rD, $sym($rA)">; + "la $rD, $sym($rA)", + []>; def MULLI : DForm_2< 7, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "mulli $rD, $rA, $imm">; + "mulli $rD, $rA, $imm", + [(set GPRC:$rD, (mul GPRC:$rA, immSExt16:$imm))]>; def SUBFIC : DForm_2< 8, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "subfic $rD, $rA, $imm">; + "subfic $rD, $rA, $imm", + []>; def LI : DForm_2_r0<14, (ops GPRC:$rD, s16imm:$imm), - "li $rD, $imm">; + "li $rD, $imm", + [(set GPRC:$rD, immSExt16:$imm)]>; def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm), - "lis $rD, $imm">; + "lis $rD, $imm", + [(set GPRC:$rD, imm16Shifted:$imm)]>; let isStore = 1 in { def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), "stmw $rS, $disp($rA)">; From lattner at cs.uiuc.edu Thu Sep 8 12:41:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 12:41:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td PowerPCInstrInfo.td Message-ID: <200509081741.MAA25259@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrFormats.td updated: 1.49 -> 1.50 PowerPCInstrInfo.td updated: 1.92 -> 1.93 --- Log message: add patterns for x?oris? --- Diffs of the changes: (+31 -8) PowerPCInstrFormats.td | 5 ++++- PowerPCInstrInfo.td | 34 +++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.49 llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.50 --- llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.49 Thu Sep 8 12:33:10 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrFormats.td Thu Sep 8 12:40:49 2005 @@ -123,11 +123,14 @@ class DForm_3 opcode, dag OL, string asmstr> : DForm_1; -class DForm_4 opcode, dag OL, string asmstr> : I { +class DForm_4 opcode, dag OL, string asmstr, list pattern> + : I { bits<5> B; bits<5> A; bits<16> C; + let Pattern = pattern; + let Inst{6-10} = A; let Inst{11-15} = B; let Inst{16-31} = C; Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.92 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.93 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.92 Thu Sep 8 12:33:10 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 8 12:40:49 2005 @@ -72,15 +72,29 @@ // field. Used by instructions like 'addi'. return (int)N->getValue() == (short)N->getValue(); }]>; +def immZExt16 : PatLeaf<(imm), [{ + // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended + // field. Used by instructions like 'ori'. + return (unsigned)N->getValue() == (unsigned short)N->getValue(); +}]>; def imm16Shifted : PatLeaf<(imm), [{ // imm16Shifted predicate - True if only bits in the top 16-bits of the // immediate are set. Used by instructions like 'addis'. return ((unsigned)N->getValue() & 0xFFFF0000U) == (unsigned)N->getValue(); }], [{ - // Transformation predicate: shift the immediate value down into the low bits. + // Transformation function: shift the immediate value down into the low bits. return getI32Imm((unsigned)N->getValue() >> 16); }]>; +/* +// Example of a legalize expander: Only for PPC64. +def : Expander<(set i64:$dst, (fp_to_sint f64:$src)), + [(set f64:$tmp , (FCTIDZ f64:$src)), + (set i32:$tmpFI, (CreateNewFrameIndex 8, 8)), + (store f64:$tmp, i32:$tmpFI), + (set i64:$dst, (load i32:$tmpFI))], + Subtarget_PPC64>; +*/ class isPPC64 { bit PPC64 = 1; } class isVMX { bit VMX = 1; } @@ -238,17 +252,23 @@ "stwu $rS, $disp($rA)">; } def ANDIo : DForm_4<28, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "andi. $dst, $src1, $src2">, isDOT; + "andi. $dst, $src1, $src2", + []>, isDOT; def ANDISo : DForm_4<29, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "andis. $dst, $src1, $src2">, isDOT; + "andis. $dst, $src1, $src2", + []>, isDOT; def ORI : DForm_4<24, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "ori $dst, $src1, $src2">; + "ori $dst, $src1, $src2", + [(set GPRC:$rD, (or GPRC:$rA, immZExt16:$imm))]>; def ORIS : DForm_4<25, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "oris $dst, $src1, $src2">; + "oris $dst, $src1, $src2", + [(set GPRC:$rD, (or GPRC:$rA, imm16Shifted:$imm))]>; def XORI : DForm_4<26, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "xori $dst, $src1, $src2">; + "xori $dst, $src1, $src2", + [(set GPRC:$rD, (xor GPRC:$rA, immZExt16:$imm))]>; def XORIS : DForm_4<27, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "xoris $dst, $src1, $src2">; + "xoris $dst, $src1, $src2", + [(set GPRC:$rD, (xor GPRC:$rA, imm16Shifted:$imm))]>; def NOP : DForm_4_zero<24, (ops), "nop">; def CMPI : DForm_5<11, (ops CRRC:$crD, i1imm:$L, GPRC:$rA, s16imm:$imm), "cmpi $crD, $L, $rA, $imm">; From lattner at cs.uiuc.edu Thu Sep 8 12:45:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 12:45:23 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509081745.MAA25350@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.1 -> 1.2 --- Log message: Keep names even when inlining. This allows us to realize that ADDI is: (set GPRC:i32:$rD, (add GPRC:i32:$rA, (imm)<>:$imm)) not: (set GPRC:i32:$rD, (add GPRC:i32:$rA, (imm)<>)) (we keep the ":$imm") --- Diffs of the changes: (+2 -1) DAGISelEmitter.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.1 llvm/utils/TableGen/DAGISelEmitter.cpp:1.2 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.1 Wed Sep 7 18:44:43 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 12:45:12 2005 @@ -142,6 +142,8 @@ FragTree->SubstituteFormalArguments(ArgMap); } + FragTree->setName(getName()); + // Get a new copy of this fragment to stitch into here. //delete this; // FIXME: implement refcounting! return FragTree; @@ -420,7 +422,6 @@ // Inline pattern fragments into it. Instructions.back()->InlinePatternFragments(); - DEBUG(std::cerr << Instrs[i]->getName() << ": "); DEBUG(Instructions.back()->dump()); } } From lattner at cs.uiuc.edu Thu Sep 8 13:22:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 13:22:48 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200509081822.NAA25751@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.33 -> 1.34 --- Log message: Tabs to spaces. --- Diffs of the changes: (+12 -12) FileParser.y | 24 ++++++++++++------------ 1 files changed, 12 insertions(+), 12 deletions(-) Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.33 llvm/utils/TableGen/FileParser.y:1.34 --- llvm/utils/TableGen/FileParser.y:1.33 Mon Apr 18 22:36:21 2005 +++ llvm/utils/TableGen/FileParser.y Thu Sep 8 13:22:35 2005 @@ -153,8 +153,8 @@ // value or leaving them as the default if necessary. for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { if (i < TemplateArgs.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateArgs[i]); + // Set it now. + setValue(TArgs[i], 0, TemplateArgs[i]); // Resolve it next. CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); @@ -164,10 +164,10 @@ CurRec->removeValue(TArgs[i]); } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of subclass '" << SC->getName() - << "'!\n"; - exit(1); + err() << "ERROR: Value not specified for template argument #" + << i << " (" << TArgs[i] << ") of subclass '" << SC->getName() + << "'!\n"; + exit(1); } } } @@ -268,9 +268,9 @@ for (unsigned i = 0, e = $2->size(); i != e; ++i) { struct Init *Bit = (*$2)[i]->convertInitializerTo(new BitRecTy()); if (Bit == 0) { - err() << "Element #" << i << " (" << *(*$2)[i] - << ") is not convertable to a bit!\n"; - exit(1); + err() << "Element #" << i << " (" << *(*$2)[i] + << ") is not convertable to a bit!\n"; + exit(1); } Init->setBit($2->size()-i-1, Bit); } @@ -515,14 +515,14 @@ } OptTemplateArgList ClassList { ParsingTemplateArgs = false; for (unsigned i = 0, e = $4->size(); i != e; ++i) { - addSubClass((*$4)[i].first, *(*$4)[i].second); + addSubClass((*$4)[i].first, *(*$4)[i].second); // Delete the template arg values for the class delete (*$4)[i].second; } delete $4; // Delete the class list... - // Process any variables on the set stack... - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) + // Process any variables on the set stack... + for (unsigned i = 0, e = LetStack.size(); i != e; ++i) for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) setValue(LetStack[i][j].Name, LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, From lattner at cs.uiuc.edu Thu Sep 8 13:23:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 13:23:08 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.cpp FileParser.h Message-ID: <200509081823.NAA25786@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.cpp updated: 1.1 -> 1.2 FileParser.h updated: 1.1 -> 1.2 --- Log message: regenerate --- Diffs of the changes: (+1140 -1629) FileParser.cpp | 2658 +++++++++++++++++++++++---------------------------------- FileParser.h | 111 -- 2 files changed, 1140 insertions(+), 1629 deletions(-) Index: llvm/utils/TableGen/FileParser.cpp diff -u llvm/utils/TableGen/FileParser.cpp:1.1 llvm/utils/TableGen/FileParser.cpp:1.2 --- llvm/utils/TableGen/FileParser.cpp:1.1 Sat Aug 27 13:50:39 2005 +++ llvm/utils/TableGen/FileParser.cpp Thu Sep 8 13:22:57 2005 @@ -1,115 +1,38 @@ -/* A Bison parser, made by GNU Bison 1.875c. */ -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +/* A Bison parser, made from /Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y + by GNU Bison version 1.28 */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ +#define YYBISON 1 /* Identify Bison output. */ -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - -/* If NAME_PREFIX is specified substitute the variables and functions - names. */ #define yyparse Fileparse -#define yylex Filelex +#define yylex Filelex #define yyerror Fileerror -#define yylval Filelval -#define yychar Filechar +#define yylval Filelval +#define yychar Filechar #define yydebug Filedebug #define yynerrs Filenerrs +#define INT 257 +#define BIT 258 +#define STRING 259 +#define BITS 260 +#define LIST 261 +#define CODE 262 +#define DAG 263 +#define CLASS 264 +#define DEF 265 +#define FIELD 266 +#define LET 267 +#define IN 268 +#define SHLTOK 269 +#define SRATOK 270 +#define SRLTOK 271 +#define INTVAL 272 +#define ID 273 +#define VARNAME 274 +#define STRVAL 275 +#define CODEFRAGMENT 276 - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - INT = 258, - BIT = 259, - STRING = 260, - BITS = 261, - LIST = 262, - CODE = 263, - DAG = 264, - CLASS = 265, - DEF = 266, - FIELD = 267, - LET = 268, - IN = 269, - SHLTOK = 270, - SRATOK = 271, - SRLTOK = 272, - INTVAL = 273, - ID = 274, - VARNAME = 275, - STRVAL = 276, - CODEFRAGMENT = 277 - }; -#endif -#define INT 258 -#define BIT 259 -#define STRING 260 -#define BITS 261 -#define LIST 262 -#define CODE 263 -#define DAG 264 -#define CLASS 265 -#define DEF 266 -#define FIELD 267 -#define LET 268 -#define IN 269 -#define SHLTOK 270 -#define SRATOK 271 -#define SRLTOK 272 -#define INTVAL 273 -#define ID 274 -#define VARNAME 275 -#define STRVAL 276 -#define CODEFRAGMENT 277 - - - - -/* Copy the first part of user declarations. */ -#line 14 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" +#line 14 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" #include "Record.h" #include "llvm/ADT/StringExtras.h" @@ -252,8 +175,8 @@ // value or leaving them as the default if necessary. for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { if (i < TemplateArgs.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateArgs[i]); + // Set it now. + setValue(TArgs[i], 0, TemplateArgs[i]); // Resolve it next. CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); @@ -263,10 +186,10 @@ CurRec->removeValue(TArgs[i]); } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of subclass '" << SC->getName() - << "'!\n"; - exit(1); + err() << "ERROR: Value not specified for template argument #" + << i << " (" << TArgs[i] << ") of subclass '" << SC->getName() + << "'!\n"; + exit(1); } } } @@ -284,23 +207,8 @@ using namespace llvm; - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 189 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" -typedef union YYSTYPE { +#line 189 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +typedef union { std::string* StrVal; int IntVal; llvm::RecTy* Ty; @@ -312,835 +220,535 @@ std::vector* SubClassList; std::vector >* DagValueList; } YYSTYPE; -/* Line 191 of yacc.c. */ -#line 317 "FileParser.tab.c" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 214 of yacc.c. */ -#line 329 "FileParser.tab.c" - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -# ifndef YYFREE -# define YYFREE free -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# endif - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# endif -# else -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined (__GNUC__) && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) +#include +#ifndef __cplusplus +#ifndef __STDC__ +#define const #endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short yysigned_char; #endif -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 18 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 149 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 38 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 37 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 84 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 152 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 277 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 32, 33, 2, 2, 34, 36, 31, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 35, 37, - 23, 25, 24, 26, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 29, 2, 30, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 27, 2, 28, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22 -}; -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned char yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 14, 16, 21, 23, - 25, 27, 28, 30, 31, 34, 36, 38, 40, 42, - 46, 48, 53, 57, 61, 66, 71, 78, 85, 92, - 93, 96, 99, 104, 105, 107, 109, 113, 116, 120, - 126, 131, 133, 134, 138, 139, 141, 143, 147, 152, - 155, 162, 163, 166, 168, 172, 174, 179, 181, 185, - 186, 189, 191, 195, 199, 200, 202, 204, 205, 206, - 207, 214, 217, 220, 222, 224, 229, 231, 235, 236, - 241, 246, 249, 251, 254 + +#define YYFINAL 152 +#define YYFLAG -32768 +#define YYNTBASE 38 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 74) + +static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, + 33, 2, 2, 34, 36, 31, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 35, 37, 23, + 25, 24, 26, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 29, 2, 30, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 27, 2, 28, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22 }; -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yysigned_char yyrhs[] = -{ - 74, 0, -1, 19, -1, 5, -1, 4, -1, 6, - 23, 18, 24, -1, 3, -1, 7, 23, 40, 24, - -1, 8, -1, 9, -1, 39, -1, -1, 12, -1, - -1, 25, 43, -1, 18, -1, 21, -1, 22, -1, - 26, -1, 27, 50, 28, -1, 19, -1, 43, 27, - 48, 28, -1, 29, 50, 30, -1, 43, 31, 19, - -1, 32, 19, 46, 33, -1, 43, 29, 48, 30, - -1, 15, 32, 43, 34, 43, 33, -1, 16, 32, - 43, 34, 43, 33, -1, 17, 32, 43, 34, 43, - 33, -1, -1, 35, 20, -1, 43, 44, -1, 45, - 34, 43, 44, -1, -1, 45, -1, 18, -1, 18, - 36, 18, -1, 18, 18, -1, 47, 34, 18, -1, - 47, 34, 18, 36, 18, -1, 47, 34, 18, 18, - -1, 47, -1, -1, 27, 48, 28, -1, -1, 51, - -1, 43, -1, 51, 34, 43, -1, 41, 40, 19, - 42, -1, 52, 37, -1, 13, 19, 49, 25, 43, - 37, -1, -1, 54, 53, -1, 37, -1, 27, 54, - 28, -1, 39, -1, 39, 23, 51, 24, -1, 56, - -1, 57, 34, 56, -1, -1, 35, 57, -1, 52, - -1, 59, 34, 52, -1, 23, 59, 24, -1, -1, - 60, -1, 19, -1, -1, -1, -1, 62, 64, 61, - 58, 65, 55, -1, 10, 63, -1, 11, 63, -1, - 66, -1, 67, -1, 19, 49, 25, 43, -1, 69, - -1, 70, 34, 69, -1, -1, 13, 72, 70, 14, - -1, 71, 27, 73, 28, -1, 71, 68, -1, 68, - -1, 73, 68, -1, 73, -1 +#if YYDEBUG != 0 +static const short yyprhs[] = { 0, + 0, 2, 4, 6, 11, 13, 18, 20, 22, 24, + 25, 27, 28, 31, 33, 35, 37, 39, 43, 45, + 50, 54, 58, 63, 68, 75, 82, 89, 90, 93, + 96, 101, 102, 104, 106, 110, 113, 117, 123, 128, + 130, 131, 135, 136, 138, 140, 144, 149, 152, 159, + 160, 163, 165, 169, 171, 176, 178, 182, 183, 186, + 188, 192, 196, 197, 199, 201, 202, 203, 204, 211, + 214, 217, 219, 221, 226, 228, 232, 233, 238, 243, + 246, 248, 251 }; -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short yyrline[] = -{ - 0, 223, 223, 234, 236, 238, 240, 242, 244, 246, - 248, 252, 252, 254, 254, 256, 258, 261, 264, 266, - 279, 294, 301, 304, 311, 319, 327, 333, 339, 347, - 350, 354, 359, 365, 368, 371, 374, 387, 401, 403, - 416, 432, 434, 434, 438, 440, 444, 447, 451, 461, - 463, 469, 469, 470, 470, 472, 474, 478, 483, 488, - 491, 495, 498, 503, 504, 504, 506, 506, 508, 515, - 508, 535, 543, 560, 560, 562, 567, 567, 570, 570, - 573, 576, 580, 580, 582 +static const short yyrhs[] = { 19, + 0, 5, 0, 4, 0, 6, 23, 18, 24, 0, + 3, 0, 7, 23, 39, 24, 0, 8, 0, 9, + 0, 38, 0, 0, 12, 0, 0, 25, 42, 0, + 18, 0, 21, 0, 22, 0, 26, 0, 27, 49, + 28, 0, 19, 0, 42, 27, 47, 28, 0, 29, + 49, 30, 0, 42, 31, 19, 0, 32, 19, 45, + 33, 0, 42, 29, 47, 30, 0, 15, 32, 42, + 34, 42, 33, 0, 16, 32, 42, 34, 42, 33, + 0, 17, 32, 42, 34, 42, 33, 0, 0, 35, + 20, 0, 42, 43, 0, 44, 34, 42, 43, 0, + 0, 44, 0, 18, 0, 18, 36, 18, 0, 18, + 18, 0, 46, 34, 18, 0, 46, 34, 18, 36, + 18, 0, 46, 34, 18, 18, 0, 46, 0, 0, + 27, 47, 28, 0, 0, 50, 0, 42, 0, 50, + 34, 42, 0, 40, 39, 19, 41, 0, 51, 37, + 0, 13, 19, 48, 25, 42, 37, 0, 0, 53, + 52, 0, 37, 0, 27, 53, 28, 0, 38, 0, + 38, 23, 50, 24, 0, 55, 0, 56, 34, 55, + 0, 0, 35, 56, 0, 51, 0, 58, 34, 51, + 0, 23, 58, 24, 0, 0, 59, 0, 19, 0, + 0, 0, 0, 61, 63, 60, 57, 64, 54, 0, + 10, 62, 0, 11, 62, 0, 65, 0, 66, 0, + 19, 48, 25, 42, 0, 68, 0, 69, 34, 68, + 0, 0, 13, 71, 69, 14, 0, 70, 27, 72, + 28, 0, 70, 67, 0, 67, 0, 72, 67, 0, + 72, 0 }; + #endif -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "INT", "BIT", "STRING", "BITS", "LIST", - "CODE", "DAG", "CLASS", "DEF", "FIELD", "LET", "IN", "SHLTOK", "SRATOK", - "SRLTOK", "INTVAL", "ID", "VARNAME", "STRVAL", "CODEFRAGMENT", "'<'", - "'>'", "'='", "'?'", "'{'", "'}'", "'['", "']'", "'.'", "'('", "')'", - "','", "':'", "'-'", "';'", "$accept", "ClassID", "Type", "OptPrefix", - "OptValue", "Value", "OptVarName", "DagArgListNE", "DagArgList", - "RBitList", "BitList", "OptBitList", "ValueList", "ValueListNE", - "Declaration", "BodyItem", "BodyList", "Body", "SubClassRef", - "ClassListNE", "ClassList", "DeclListNE", "TemplateArgList", - "OptTemplateArgList", "OptID", "ObjectBody", "@1", "@2", "ClassInst", - "DefInst", "Object", "LETItem", "LETList", "LETCommand", "@3", - "ObjectList", "File", 0 +#if YYDEBUG != 0 +static const short yyrline[] = { 0, + 223, 234, 236, 238, 240, 242, 244, 246, 248, 252, + 252, 254, 254, 256, 258, 261, 264, 266, 279, 294, + 301, 304, 311, 319, 327, 333, 339, 347, 350, 354, + 359, 365, 368, 371, 374, 387, 401, 403, 416, 432, + 434, 434, 438, 440, 444, 447, 451, 461, 463, 469, + 469, 470, 470, 472, 474, 478, 483, 488, 491, 495, + 498, 503, 504, 504, 506, 506, 508, 515, 530, 535, + 543, 560, 560, 562, 567, 567, 570, 570, 573, 576, + 580, 580, 582 }; #endif -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 60, 62, 61, 63, 123, 125, 91, - 93, 46, 40, 41, 44, 58, 45, 59 -}; -# endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 38, 39, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 42, 42, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, - 44, 45, 45, 46, 46, 47, 47, 47, 47, 47, - 47, 48, 49, 49, 50, 50, 51, 51, 52, 53, - 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, - 58, 59, 59, 60, 61, 61, 62, 62, 64, 65, - 63, 66, 67, 68, 68, 69, 70, 70, 72, 71, - 68, 68, 73, 73, 74 +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) + +static const char * const yytname[] = { "$","error","$undefined.","INT","BIT", +"STRING","BITS","LIST","CODE","DAG","CLASS","DEF","FIELD","LET","IN","SHLTOK", +"SRATOK","SRLTOK","INTVAL","ID","VARNAME","STRVAL","CODEFRAGMENT","'<'","'>'", +"'='","'?'","'{'","'}'","'['","']'","'.'","'('","')'","','","':'","'-'","';'", +"ClassID","Type","OptPrefix","OptValue","Value","OptVarName","DagArgListNE", +"DagArgList","RBitList","BitList","OptBitList","ValueList","ValueListNE","Declaration", +"BodyItem","BodyList","Body","SubClassRef","ClassListNE","ClassList","DeclListNE", +"TemplateArgList","OptTemplateArgList","OptID","ObjectBody","@1","@2","ClassInst", +"DefInst","Object","LETItem","LETList","LETCommand","@3","ObjectList","File", NULL }; +#endif -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 1, 1, 1, 4, 1, 4, 1, 1, - 1, 0, 1, 0, 2, 1, 1, 1, 1, 3, - 1, 4, 3, 3, 4, 4, 6, 6, 6, 0, - 2, 2, 4, 0, 1, 1, 3, 2, 3, 5, - 4, 1, 0, 3, 0, 1, 1, 3, 4, 2, - 6, 0, 2, 1, 3, 1, 4, 1, 3, 0, - 2, 1, 3, 3, 0, 1, 1, 0, 0, 0, - 6, 2, 2, 1, 1, 4, 1, 3, 0, 4, - 4, 2, 1, 2, 1 +static const short yyr1[] = { 0, + 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, + 40, 41, 41, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 43, 43, 44, + 44, 45, 45, 46, 46, 46, 46, 46, 46, 47, + 48, 48, 49, 49, 50, 50, 51, 52, 52, 53, + 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, + 58, 59, 60, 60, 61, 61, 63, 64, 62, 65, + 66, 67, 67, 68, 69, 69, 71, 70, 67, 67, + 72, 72, 73 }; -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 0, 67, 67, 78, 73, 74, 82, 0, 84, 0, - 66, 68, 71, 72, 0, 0, 81, 83, 1, 64, - 42, 76, 0, 0, 11, 65, 59, 0, 0, 79, - 0, 80, 12, 0, 61, 0, 0, 69, 35, 41, - 0, 0, 77, 6, 4, 3, 0, 0, 8, 9, - 2, 10, 0, 63, 11, 55, 57, 60, 0, 37, - 0, 0, 43, 0, 0, 0, 15, 20, 16, 17, - 18, 44, 44, 0, 75, 0, 0, 13, 62, 0, - 0, 51, 53, 70, 36, 38, 0, 0, 0, 46, - 0, 45, 0, 33, 0, 0, 0, 0, 0, 0, - 48, 0, 58, 11, 40, 0, 0, 0, 0, 19, - 0, 22, 29, 34, 0, 0, 0, 23, 5, 7, - 14, 56, 0, 54, 0, 52, 39, 0, 0, 0, - 47, 0, 31, 0, 24, 21, 25, 42, 49, 0, - 0, 0, 30, 29, 0, 26, 27, 28, 32, 0, - 0, 50 +static const short yyr2[] = { 0, + 1, 1, 1, 4, 1, 4, 1, 1, 1, 0, + 1, 0, 2, 1, 1, 1, 1, 3, 1, 4, + 3, 3, 4, 4, 6, 6, 6, 0, 2, 2, + 4, 0, 1, 1, 3, 2, 3, 5, 4, 1, + 0, 3, 0, 1, 1, 3, 4, 2, 6, 0, + 2, 1, 3, 1, 4, 1, 3, 0, 2, 1, + 3, 3, 0, 1, 1, 0, 0, 0, 6, 2, + 2, 1, 1, 4, 1, 3, 0, 4, 4, 2, + 1, 2, 1 }; -/* YYDEFGOTO[NTERM-NUM]. */ -static const short yydefgoto[] = -{ - -1, 51, 52, 33, 100, 89, 132, 113, 114, 39, - 40, 28, 90, 91, 34, 125, 103, 83, 56, 57, - 37, 35, 25, 26, 11, 12, 19, 58, 4, 5, - 6, 21, 22, 7, 14, 8, 9 +static const short yydefact[] = { 0, + 66, 66, 77, 72, 73, 81, 0, 83, 65, 67, + 70, 71, 0, 0, 80, 82, 63, 41, 75, 0, + 0, 10, 64, 58, 0, 0, 78, 0, 79, 11, + 0, 60, 0, 0, 68, 34, 40, 0, 0, 76, + 5, 3, 2, 0, 0, 7, 8, 1, 9, 0, + 62, 10, 54, 56, 59, 0, 36, 0, 0, 42, + 0, 0, 0, 14, 19, 15, 16, 17, 43, 43, + 0, 74, 0, 0, 12, 61, 0, 0, 50, 52, + 69, 35, 37, 0, 0, 0, 45, 0, 44, 0, + 32, 0, 0, 0, 0, 0, 0, 47, 0, 57, + 10, 39, 0, 0, 0, 0, 18, 0, 21, 28, + 33, 0, 0, 0, 22, 4, 6, 13, 55, 0, + 53, 0, 51, 38, 0, 0, 0, 46, 0, 30, + 0, 23, 20, 24, 41, 48, 0, 0, 0, 29, + 28, 0, 25, 26, 27, 31, 0, 0, 49, 0, + 0, 0 }; -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -54 -static const yysigned_char yypact[] = -{ - 61, -7, -7, -54, -54, -54, -54, 4, 61, 24, - -54, -54, -54, -54, 23, 61, -54, -54, -54, 18, - 29, -54, -12, -5, 55, -54, 38, 65, 69, -54, - 23, -54, -54, 56, -54, -14, 71, -54, -15, 64, - 72, 11, -54, -54, -54, -54, 81, 83, -54, -54, - -54, -54, 91, -54, 55, 89, -54, 80, 12, -54, - 100, 101, -54, 88, 90, 92, -54, -54, -54, -54, - -54, 11, 11, 102, 26, 105, 56, 103, -54, 11, - 71, -54, -54, -54, -54, -11, 11, 11, 11, 26, - 97, 93, 96, 11, 65, 65, 110, 106, 107, 11, - -54, 20, -54, 6, -54, 114, -18, 62, 68, -54, - 11, -54, 50, 99, 104, 108, 109, -54, -54, -54, - 26, -54, 115, -54, 98, -54, -54, 11, 11, 11, - 26, 118, -54, 11, -54, -54, -54, 29, -54, 51, - 74, 82, -54, 50, 116, -54, -54, -54, -54, 11, - 39, -54 +static const short yydefgoto[] = { 49, + 50, 31, 98, 87, 130, 111, 112, 37, 38, 26, + 88, 89, 32, 123, 101, 81, 54, 55, 35, 33, + 23, 24, 10, 11, 17, 56, 4, 5, 6, 19, + 20, 7, 13, 8, 150 }; -/* YYPGOTO[NTERM-NUM]. */ -static const short yypgoto[] = -{ - -54, -32, 66, -54, -54, -41, -3, -54, -54, -54, - 22, 7, 73, 67, -53, -54, -54, -54, 63, -54, - -54, -54, -54, -54, -54, 145, -54, -54, -54, -54, - 28, 119, -54, -54, -54, 133, -54 +static const short yypact[] = { 61, + -10, -10,-32768,-32768,-32768,-32768, 4, 61,-32768,-32768, +-32768,-32768, -3, 61,-32768,-32768, 12, -7,-32768, -12, + -5, 24,-32768, 7, 38, 42,-32768, -3,-32768,-32768, + 56,-32768, 15, 54,-32768, -15, 49, 66, 11,-32768, +-32768,-32768,-32768, 67, 75,-32768,-32768,-32768,-32768, 81, +-32768, 24, 78,-32768, 70, 14,-32768, 88, 99,-32768, + 87, 89, 90,-32768,-32768,-32768,-32768,-32768, 11, 11, + 101, 26, 105, 56, 100,-32768, 11, 54,-32768,-32768, +-32768,-32768, -11, 11, 11, 11, 26, 96, 92, 97, + 11, 38, 38, 109, 106, 107, 11,-32768, 20,-32768, + 6,-32768, 111, 62, 68, 76,-32768, 11,-32768, 50, + 98, 102, 108, 103,-32768,-32768,-32768, 26,-32768, 115, +-32768, 104,-32768,-32768, 11, 11, 11, 26, 117,-32768, + 11,-32768,-32768,-32768, -7,-32768, 51, 82, 85,-32768, + 50, 113,-32768,-32768,-32768,-32768, 11, 39,-32768, 139, + 140,-32768 }; -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const unsigned char yytable[] = -{ - 74, 78, 29, 59, 55, 1, 2, 104, 3, 94, - 53, 95, 10, 96, 1, 2, 127, 3, 32, 122, - 54, 60, 30, 31, 18, 105, 63, 64, 65, 66, - 67, 15, 68, 69, 123, 16, 17, 70, 71, 81, - 72, 24, 20, 73, 121, 106, 107, 108, 55, 82, - 124, 17, 112, 94, 110, 95, 27, 96, 120, 43, - 44, 45, 46, 47, 48, 49, 94, 32, 95, 130, - 96, 1, 2, 36, 3, 50, 151, 94, 94, 95, - 95, 96, 96, 38, 145, 131, 139, 140, 141, 94, - 50, 95, 143, 96, 41, 94, 128, 95, 61, 96, - 62, 94, 129, 95, 75, 96, 76, 146, 150, 94, - 77, 95, 79, 96, 80, 147, 115, 116, 84, 85, - 86, 93, 87, 97, 88, 109, 111, 110, 99, 117, - 118, 119, 126, 133, 137, 138, 135, 134, 142, 136, - 148, 149, 98, 102, 144, 92, 101, 13, 23, 42 +static const short yypgoto[] = { -30, + 69,-32768,-32768, -39, 1,-32768,-32768,-32768, -80, 9, + 77, 71, -51,-32768,-32768,-32768, 72,-32768,-32768,-32768, +-32768,-32768,-32768, 143,-32768,-32768,-32768,-32768, 3, 118, +-32768,-32768,-32768, 135,-32768 }; -static const unsigned char yycheck[] = -{ - 41, 54, 14, 18, 36, 10, 11, 18, 13, 27, - 24, 29, 19, 31, 10, 11, 34, 13, 12, 13, - 34, 36, 34, 28, 0, 36, 15, 16, 17, 18, - 19, 27, 21, 22, 28, 7, 8, 26, 27, 27, - 29, 23, 19, 32, 24, 86, 87, 88, 80, 37, - 103, 23, 93, 27, 34, 29, 27, 31, 99, 3, - 4, 5, 6, 7, 8, 9, 27, 12, 29, 110, - 31, 10, 11, 35, 13, 19, 37, 27, 27, 29, - 29, 31, 31, 18, 33, 35, 127, 128, 129, 27, - 19, 29, 133, 31, 25, 27, 34, 29, 34, 31, - 28, 27, 34, 29, 23, 31, 23, 33, 149, 27, - 19, 29, 23, 31, 34, 33, 94, 95, 18, 18, - 32, 19, 32, 18, 32, 28, 30, 34, 25, 19, - 24, 24, 18, 34, 19, 37, 28, 33, 20, 30, - 143, 25, 76, 80, 137, 72, 79, 2, 15, 30 + +#define YYLAST 150 + + +static const short yytable[] = { 72, + 76, 27, 57, 53, 1, 2, 102, 3, 9, 15, + 16, 113, 114, 1, 2, 18, 3, 30, 120, 25, + 58, 28, 29, 16, 103, 61, 62, 63, 64, 65, + 14, 66, 67, 121, 22, 30, 68, 69, 51, 70, + 79, 34, 71, 119, 104, 105, 106, 53, 52, 122, + 80, 110, 92, 108, 93, 36, 94, 118, 41, 42, + 43, 44, 45, 46, 47, 92, 39, 93, 128, 94, + 1, 2, 48, 3, 48, 149, 92, 92, 93, 93, + 94, 94, 59, 143, 129, 137, 138, 139, 92, 73, + 93, 141, 94, 60, 92, 125, 93, 74, 94, 75, + 77, 126, 92, 78, 93, 82, 94, 148, 92, 127, + 93, 92, 94, 93, 144, 94, 83, 145, 84, 91, + 85, 86, 95, 107, 97, 108, 109, 115, 124, 116, + 117, 131, 134, 135, 132, 133, 140, 147, 151, 152, + 136, 146, 96, 142, 12, 40, 90, 99, 21, 100 }; -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 10, 11, 13, 66, 67, 68, 71, 73, 74, - 19, 62, 63, 63, 72, 27, 68, 68, 0, 64, - 19, 69, 70, 73, 23, 60, 61, 27, 49, 14, - 34, 28, 12, 41, 52, 59, 35, 58, 18, 47, - 48, 25, 69, 3, 4, 5, 6, 7, 8, 9, - 19, 39, 40, 24, 34, 39, 56, 57, 65, 18, - 36, 34, 28, 15, 16, 17, 18, 19, 21, 22, - 26, 27, 29, 32, 43, 23, 23, 19, 52, 23, - 34, 27, 37, 55, 18, 18, 32, 32, 32, 43, - 50, 51, 50, 19, 27, 29, 31, 18, 40, 25, - 42, 51, 56, 54, 18, 36, 43, 43, 43, 28, - 34, 30, 43, 45, 46, 48, 48, 19, 24, 24, - 43, 24, 13, 28, 52, 53, 18, 34, 34, 34, - 43, 35, 44, 34, 33, 28, 30, 19, 37, 43, - 43, 43, 20, 43, 49, 33, 33, 33, 44, 25, - 43, 37 +static const short yycheck[] = { 39, + 52, 14, 18, 34, 10, 11, 18, 13, 19, 7, + 8, 92, 93, 10, 11, 19, 13, 12, 13, 27, + 36, 34, 28, 21, 36, 15, 16, 17, 18, 19, + 27, 21, 22, 28, 23, 12, 26, 27, 24, 29, + 27, 35, 32, 24, 84, 85, 86, 78, 34, 101, + 37, 91, 27, 34, 29, 18, 31, 97, 3, 4, + 5, 6, 7, 8, 9, 27, 25, 29, 108, 31, + 10, 11, 19, 13, 19, 37, 27, 27, 29, 29, + 31, 31, 34, 33, 35, 125, 126, 127, 27, 23, + 29, 131, 31, 28, 27, 34, 29, 23, 31, 19, + 23, 34, 27, 34, 29, 18, 31, 147, 27, 34, + 29, 27, 31, 29, 33, 31, 18, 33, 32, 19, + 32, 32, 18, 28, 25, 34, 30, 19, 18, 24, + 24, 34, 30, 19, 33, 28, 20, 25, 0, 0, + 37, 141, 74, 135, 2, 28, 70, 77, 14, 78 }; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/share/bison.simple" +/* This file comes from bison-1.28. */ -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +#ifndef YYSTACK_USE_ALLOCA +#ifdef alloca +#define YYSTACK_USE_ALLOCA +#else /* alloca not defined */ +#ifdef __GNUC__ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) +#define YYSTACK_USE_ALLOCA +#include +#else /* not sparc */ +/* We think this test detects Watcom and Microsoft C. */ +/* This used to test MSDOS, but that is a bad idea + since that symbol is in the user namespace. */ +#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) +#if 0 /* No need for malloc.h, which pollutes the namespace; + instead, just don't use alloca. */ +#include +#endif +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +/* I don't know what this was needed for, but it pollutes the namespace. + So I turned it off. rms, 2 May 1997. */ +/* #include */ + #pragma alloca +#define YYSTACK_USE_ALLOCA +#else /* not MSDOS, or __TURBOC__, or _AIX */ +#if 0 +#ifdef __hpux /* haible at ilog.fr says this works for HPUX 9.05 and up, + and on HPUX 10. Eventually we can turn this on. */ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#endif /* __hpux */ +#endif +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc */ +#endif /* not GNU C */ +#endif /* alloca not defined */ +#endif /* YYSTACK_USE_ALLOCA not defined */ + +#ifdef YYSTACK_USE_ALLOCA +#define YYSTACK_ALLOC alloca +#else +#define YYSTACK_ALLOC malloc #endif +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) +#define YYEMPTY -2 #define YYEOF 0 - #define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ - #define YYFAIL goto yyerrlab - #define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ +#define YYBACKUP(token, value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ - { \ - yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - ((Current).first_line = (Rhs)[1].first_line, \ - (Current).first_column = (Rhs)[1].first_column, \ - (Current).last_line = (Rhs)[N].last_line, \ - (Current).last_column = (Rhs)[N].last_column) +#ifndef YYPURE +#define YYLEX yylex() #endif -/* YYLEX -- calling `yylex' with the right arguments. */ - +#ifdef YYPURE +#ifdef YYLSP_NEEDED #ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) #else -# define YYLEX yylex () +#define YYLEX yylex(&yylval, &yylloc) #endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short *bottom, short *top) +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) #else -static void -yy_stack_print (bottom, top) - short *bottom; - short *top; +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ #endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) +/* If nonreentrant, generate the variables here */ +#ifndef YYPURE -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ #endif -{ - int yyi; - unsigned int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -} -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif +/* YYINITDEPTH indicates the initial size of the parser's stacks */ -/* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH -# define YYINITDEPTH 200 +#define YYINITDEPTH 200 #endif -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ -#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 -# undef YYMAXDEPTH +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 +#define YYMAXDEPTH 10000 #endif - +/* Define __yy_memcpy. Note that the size argument + should be passed with type unsigned int, because that is what the non-GCC + definitions require. With GCC, __builtin_memcpy takes an arg + of type size_t, but it can handle unsigned int. */ + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (to, from, count) + char *to; + char *from; + unsigned int count; +{ + register char *f = from; + register char *t = to; + register int i = count; - return yyd - 1; + while (i-- > 0) + *t++ = *f++; } -# endif -# endif -#endif /* !YYERROR_VERBOSE */ - - +#else /* __cplusplus */ -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif +__yy_memcpy (char *to, char *from, unsigned int count) { - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; + register char *t = to; + register char *f = from; + register int i = count; - if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); + while (i-- > 0) + *t++ = *f++; } -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yytype, yyvaluep) - int yytype; - YYSTYPE *yyvaluep; #endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - switch (yytype) - { - - default: - break; - } -} +#endif +#line 217 "/usr/share/bison.simple" -/* Prevent warnings from -Wmissing-prototypes. */ +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ #ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ +#ifdef __cplusplus +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* not __cplusplus */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not YYPARSE_PARAM */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* not YYPARSE_PARAM */ +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ #ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) +int yyparse (void *); #else -int -yyparse () - +int yyparse (void); #endif #endif + +int +yyparse(YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL { - register int yystate; register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else #define YYPOPSTACK (yyvsp--, yyssp--) +#endif - YYSIZE_T yystacksize = YYINITDEPTH; + int yystacksize = YYINITDEPTH; + int yyfree_stacks = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ int yylen; - YYDPRINTF ((stderr, "Starting parse\n")); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif yystate = 0; yyerrstatus = 0; @@ -1152,96 +760,110 @@ so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; + yyssp = yyss - 1; yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: - yysetstate: - *yyssp = yystate; + *++yyssp = yystate; - if (yyss + yystacksize - 1 <= yyssp) + if (yyssp >= yyss + yystacksize - 1) { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + int size = yyssp - yyss + 1; #ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif - yyss = yyss1; - yyvs = yyvs1; - } + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif #else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); +#endif + } + return 2; + } yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) + if (yystacksize > YYMAXDEPTH) yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif +#ifndef YYSTACK_USE_ALLOCA + yyfree_stacks = 1; +#endif + yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss, (char *)yyss1, + size * (unsigned int) sizeof (*yyssp)); + yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs, (char *)yyvs1, + size * (unsigned int) sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls, (char *)yyls1, + size * (unsigned int) sizeof (*yylsp)); +#endif #endif /* no yyoverflow */ - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif - if (yyss + yystacksize - 1 <= yyssp) + if (yyssp >= yyss + yystacksize - 1) YYABORT; } - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: + yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ @@ -1250,235 +872,253 @@ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) + if (yyn == YYFLAG) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + if (yychar == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif yychar = YYLEX; } - if (yychar <= YYEOF) + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif } else { - yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif } - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) goto yydefault; + yyn = yytable[yyn]; - if (yyn <= 0) + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) { - if (yyn == 0 || yyn == YYTABLE_NINF) + if (yyn == YYFLAG) goto yyerrlab; yyn = -yyn; goto yyreduce; } + else if (yyn == 0) + goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ +/* Do the default action for the current state. */ yydefault: + yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; - goto yyreduce; - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ +/* Do a reduction. yyn is the number of a rule to reduce with. */ yyreduce: - /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. +#if YYDEBUG != 0 + if (yydebug) + { + int i; - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 223 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + + switch (yyn) { + +case 1: +#line 223 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Rec = Records.getClass(*yyvsp[0].StrVal); if (yyval.Rec == 0) { err() << "Couldn't find class '" << *yyvsp[0].StrVal << "'!\n"; exit(1); } delete yyvsp[0].StrVal; - ;} - break; - - case 3: -#line 234 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // string type + ; + break;} +case 2: +#line 234 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // string type yyval.Ty = new StringRecTy(); - ;} - break; - - case 4: -#line 236 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // bit type + ; + break;} +case 3: +#line 236 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // bit type yyval.Ty = new BitRecTy(); - ;} - break; - - case 5: -#line 238 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // bits type + ; + break;} +case 4: +#line 238 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // bits type yyval.Ty = new BitsRecTy(yyvsp[-1].IntVal); - ;} - break; - - case 6: -#line 240 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // int type + ; + break;} +case 5: +#line 240 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // int type yyval.Ty = new IntRecTy(); - ;} - break; - - case 7: -#line 242 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // list type + ; + break;} +case 6: +#line 242 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // list type yyval.Ty = new ListRecTy(yyvsp[-1].Ty); - ;} - break; - - case 8: -#line 244 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // code type + ; + break;} +case 7: +#line 244 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // code type yyval.Ty = new CodeRecTy(); - ;} - break; - - case 9: -#line 246 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // dag type + ; + break;} +case 8: +#line 246 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // dag type yyval.Ty = new DagRecTy(); - ;} - break; - - case 10: -#line 248 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { // Record Type + ; + break;} +case 9: +#line 248 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ // Record Type yyval.Ty = new RecordRecTy(yyvsp[0].Rec); - ;} - break; - - case 11: -#line 252 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.IntVal = 0; ;} - break; - - case 12: -#line 252 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.IntVal = 1; ;} - break; - - case 13: -#line 254 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.Initializer = 0; ;} - break; - - case 14: -#line 254 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.Initializer = yyvsp[0].Initializer; ;} - break; - - case 15: -#line 256 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 10: +#line 252 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.IntVal = 0; ; + break;} +case 11: +#line 252 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.IntVal = 1; ; + break;} +case 12: +#line 254 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = 0; ; + break;} +case 13: +#line 254 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[0].Initializer; ; + break;} +case 14: +#line 256 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new IntInit(yyvsp[0].IntVal); - ;} - break; - - case 16: -#line 258 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 15: +#line 258 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new StringInit(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; - ;} - break; - - case 17: -#line 261 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 16: +#line 261 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new CodeInit(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; - ;} - break; - - case 18: -#line 264 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 17: +#line 264 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new UnsetInit(); - ;} - break; - - case 19: -#line 266 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 18: +#line 266 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ BitsInit *Init = new BitsInit(yyvsp[-1].FieldList->size()); for (unsigned i = 0, e = yyvsp[-1].FieldList->size(); i != e; ++i) { struct Init *Bit = (*yyvsp[-1].FieldList)[i]->convertInitializerTo(new BitRecTy()); if (Bit == 0) { - err() << "Element #" << i << " (" << *(*yyvsp[-1].FieldList)[i] - << ") is not convertable to a bit!\n"; - exit(1); + err() << "Element #" << i << " (" << *(*yyvsp[-1].FieldList)[i] + << ") is not convertable to a bit!\n"; + exit(1); } Init->setBit(yyvsp[-1].FieldList->size()-i-1, Bit); } yyval.Initializer = Init; delete yyvsp[-1].FieldList; - ;} - break; - - case 20: -#line 279 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 19: +#line 279 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ if (const RecordVal *RV = (CurRec ? CurRec->getValue(*yyvsp[0].StrVal) : 0)) { yyval.Initializer = new VarInit(*yyvsp[0].StrVal, RV->getType()); } else if (CurRec && CurRec->isTemplateArg(CurRec->getName()+":"+*yyvsp[0].StrVal)) { @@ -1493,44 +1133,40 @@ } delete yyvsp[0].StrVal; - ;} - break; - - case 21: -#line 294 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 20: +#line 294 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->convertInitializerBitRange(*yyvsp[-1].BitList); if (yyval.Initializer == 0) { err() << "Invalid bit range for value '" << *yyvsp[-3].Initializer << "'!\n"; exit(1); } delete yyvsp[-1].BitList; - ;} - break; - - case 22: -#line 301 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 21: +#line 301 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = new ListInit(*yyvsp[-1].FieldList); delete yyvsp[-1].FieldList; - ;} - break; - - case 23: -#line 304 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 22: +#line 304 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ if (!yyvsp[-2].Initializer->getFieldType(*yyvsp[0].StrVal)) { err() << "Cannot access field '" << *yyvsp[0].StrVal << "' of value '" << *yyvsp[-2].Initializer << "!\n"; exit(1); } yyval.Initializer = new FieldInit(yyvsp[-2].Initializer, *yyvsp[0].StrVal); delete yyvsp[0].StrVal; - ;} - break; - - case 24: -#line 311 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 23: +#line 311 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ Record *D = Records.getDef(*yyvsp[-2].StrVal); if (D == 0) { err() << "Invalid def '" << *yyvsp[-2].StrVal << "'!\n"; @@ -1538,12 +1174,11 @@ } yyval.Initializer = new DagInit(D, *yyvsp[-1].DagValueList); delete yyvsp[-2].StrVal; delete yyvsp[-1].DagValueList; - ;} - break; - - case 25: -#line 319 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 24: +#line 319 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ std::reverse(yyvsp[-1].BitList->begin(), yyvsp[-1].BitList->end()); yyval.Initializer = yyvsp[-3].Initializer->convertInitListSlice(*yyvsp[-1].BitList); if (yyval.Initializer == 0) { @@ -1551,97 +1186,86 @@ exit(1); } delete yyvsp[-1].BitList; - ;} - break; - - case 26: -#line 327 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 25: +#line 327 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SHL, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { err() << "Cannot shift values '" << *yyvsp[-3].Initializer << "' and '" << *yyvsp[-1].Initializer << "'!\n"; exit(1); } - ;} - break; - - case 27: -#line 333 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 26: +#line 333 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SRA, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { err() << "Cannot shift values '" << *yyvsp[-3].Initializer << "' and '" << *yyvsp[-1].Initializer << "'!\n"; exit(1); } - ;} - break; - - case 28: -#line 339 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 27: +#line 339 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SRL, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { err() << "Cannot shift values '" << *yyvsp[-3].Initializer << "' and '" << *yyvsp[-1].Initializer << "'!\n"; exit(1); } - ;} - break; - - case 29: -#line 347 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 28: +#line 347 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = new std::string(); - ;} - break; - - case 30: -#line 350 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 29: +#line 350 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = yyvsp[0].StrVal; - ;} - break; - - case 31: -#line 354 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 30: +#line 354 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.DagValueList = new std::vector >(); yyval.DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); delete yyvsp[0].StrVal; - ;} - break; - - case 32: -#line 359 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 31: +#line 359 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyvsp[-3].DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); delete yyvsp[0].StrVal; yyval.DagValueList = yyvsp[-3].DagValueList; - ;} - break; - - case 33: -#line 365 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 32: +#line 365 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.DagValueList = new std::vector >(); - ;} - break; - - case 34: -#line 368 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.DagValueList = yyvsp[0].DagValueList; ;} - break; - - case 35: -#line 371 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 33: +#line 368 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.DagValueList = yyvsp[0].DagValueList; ; + break;} +case 34: +#line 371 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = new std::vector(); yyval.BitList->push_back(yyvsp[0].IntVal); - ;} - break; - - case 36: -#line 374 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 35: +#line 374 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; exit(1); @@ -1654,12 +1278,11 @@ for (int i = yyvsp[-2].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 37: -#line 387 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 36: +#line 387 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyvsp[0].IntVal = -yyvsp[0].IntVal; if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-1].IntVal << "-" << yyvsp[0].IntVal << "!\n"; @@ -1673,19 +1296,17 @@ for (int i = yyvsp[-1].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 38: -#line 401 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 37: +#line 401 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ (yyval.BitList=yyvsp[-2].BitList)->push_back(yyvsp[0].IntVal); - ;} - break; - - case 39: -#line 403 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 38: +#line 403 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; exit(1); @@ -1698,12 +1319,11 @@ for (int i = yyvsp[-2].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 40: -#line 416 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 39: +#line 416 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyvsp[0].IntVal = -yyvsp[0].IntVal; if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-1].IntVal << "-" << yyvsp[0].IntVal << "!\n"; @@ -1717,56 +1337,48 @@ for (int i = yyvsp[-1].IntVal; i >= yyvsp[0].IntVal; --i) yyval.BitList->push_back(i); } - ;} - break; - - case 41: -#line 432 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.BitList = yyvsp[0].BitList; std::reverse(yyvsp[0].BitList->begin(), yyvsp[0].BitList->end()); ;} - break; - - case 42: -#line 434 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.BitList = 0; ;} - break; - - case 43: -#line 434 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.BitList = yyvsp[-1].BitList; ;} - break; - - case 44: -#line 438 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 40: +#line 432 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = yyvsp[0].BitList; std::reverse(yyvsp[0].BitList->begin(), yyvsp[0].BitList->end()); ; + break;} +case 41: +#line 434 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = 0; ; + break;} +case 42: +#line 434 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.BitList = yyvsp[-1].BitList; ; + break;} +case 43: +#line 438 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.FieldList = new std::vector(); - ;} - break; - - case 45: -#line 440 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 44: +#line 440 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.FieldList = yyvsp[0].FieldList; - ;} - break; - - case 46: -#line 444 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 45: +#line 444 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.FieldList = new std::vector(); yyval.FieldList->push_back(yyvsp[0].Initializer); - ;} - break; - - case 47: -#line 447 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 46: +#line 447 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ (yyval.FieldList = yyvsp[-2].FieldList)->push_back(yyvsp[0].Initializer); - ;} - break; - - case 48: -#line 451 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 47: +#line 451 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ std::string DecName = *yyvsp[-1].StrVal; if (ParsingTemplateArgs) DecName = CurRec->getName() + ":" + DecName; @@ -1774,155 +1386,137 @@ addValue(RecordVal(DecName, yyvsp[-2].Ty, yyvsp[-3].IntVal)); setValue(DecName, 0, yyvsp[0].Initializer); yyval.StrVal = new std::string(DecName); -;} - break; - - case 49: -#line 461 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 48: +#line 461 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ delete yyvsp[-1].StrVal; -;} - break; - - case 50: -#line 463 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 49: +#line 463 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ setValue(*yyvsp[-4].StrVal, yyvsp[-3].BitList, yyvsp[-1].Initializer); delete yyvsp[-4].StrVal; delete yyvsp[-3].BitList; -;} - break; - - case 55: -#line 472 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 54: +#line 472 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassRef = new SubClassRefTy(yyvsp[0].Rec, new std::vector()); - ;} - break; - - case 56: -#line 474 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 55: +#line 474 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassRef = new SubClassRefTy(yyvsp[-3].Rec, yyvsp[-1].FieldList); - ;} - break; - - case 57: -#line 478 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 56: +#line 478 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassList = new std::vector(); yyval.SubClassList->push_back(*yyvsp[0].SubClassRef); delete yyvsp[0].SubClassRef; - ;} - break; - - case 58: -#line 483 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 57: +#line 483 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ (yyval.SubClassList=yyvsp[-2].SubClassList)->push_back(*yyvsp[0].SubClassRef); delete yyvsp[0].SubClassRef; - ;} - break; - - case 59: -#line 488 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 58: +#line 488 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassList = new std::vector(); - ;} - break; - - case 60: -#line 491 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 59: +#line 491 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.SubClassList = yyvsp[0].SubClassList; - ;} - break; - - case 61: -#line 495 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 60: +#line 495 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ CurRec->addTemplateArg(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; -;} - break; - - case 62: -#line 498 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 61: +#line 498 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ CurRec->addTemplateArg(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; -;} - break; - - case 63: -#line 503 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - {;} - break; - - case 66: -#line 506 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.StrVal = yyvsp[0].StrVal; ;} - break; - - case 67: -#line 506 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { yyval.StrVal = new std::string(); ;} - break; - - case 68: -#line 508 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 62: +#line 503 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{; + break;} +case 65: +#line 506 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = yyvsp[0].StrVal; ; + break;} +case 66: +#line 506 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.StrVal = new std::string(); ; + break;} +case 67: +#line 508 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ static unsigned AnonCounter = 0; if (yyvsp[0].StrVal->empty()) *yyvsp[0].StrVal = "anonymous."+utostr(AnonCounter++); CurRec = new Record(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; ParsingTemplateArgs = true; - ;} - break; - - case 69: -#line 515 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 68: +#line 515 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ ParsingTemplateArgs = false; for (unsigned i = 0, e = yyvsp[0].SubClassList->size(); i != e; ++i) { - addSubClass((*yyvsp[0].SubClassList)[i].first, *(*yyvsp[0].SubClassList)[i].second); + addSubClass((*yyvsp[0].SubClassList)[i].first, *(*yyvsp[0].SubClassList)[i].second); // Delete the template arg values for the class delete (*yyvsp[0].SubClassList)[i].second; } delete yyvsp[0].SubClassList; // Delete the class list... - // Process any variables on the set stack... - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) + // Process any variables on the set stack... + for (unsigned i = 0, e = LetStack.size(); i != e; ++i) for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) setValue(LetStack[i][j].Name, LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, LetStack[i][j].Value); - ;} - break; - - case 70: -#line 530 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 69: +#line 530 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Rec = CurRec; CurRec = 0; - ;} - break; - - case 71: -#line 535 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 70: +#line 535 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ if (Records.getClass(yyvsp[0].Rec->getName())) { err() << "Class '" << yyvsp[0].Rec->getName() << "' already defined!\n"; exit(1); } Records.addClass(yyval.Rec = yyvsp[0].Rec); -;} - break; - - case 72: -#line 543 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 71: +#line 543 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyvsp[0].Rec->resolveReferences(); if (!yyvsp[0].Rec->getTemplateArgs().empty()) { @@ -1936,285 +1530,269 @@ exit(1); } Records.addDef(yyval.Rec = yyvsp[0].Rec); -;} - break; - - case 75: -#line 562 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 74: +#line 562 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ LetStack.back().push_back(LetRecord(*yyvsp[-3].StrVal, yyvsp[-2].BitList, yyvsp[0].Initializer)); delete yyvsp[-3].StrVal; delete yyvsp[-2].BitList; -;} - break; - - case 78: -#line 570 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { LetStack.push_back(std::vector()); ;} - break; - - case 80: -#line 573 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { +; + break;} +case 77: +#line 570 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ LetStack.push_back(std::vector()); ; + break;} +case 79: +#line 573 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ LetStack.pop_back(); - ;} - break; - - case 81: -#line 576 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - { + ; + break;} +case 80: +#line 576 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ LetStack.pop_back(); - ;} - break; - - case 82: -#line 580 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - {;} - break; - - case 83: -#line 580 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - {;} - break; - - case 84: -#line 582 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" - {;} - break; - - - } - -/* Line 1000 of yacc.c. */ -#line 1989 "FileParser.tab.c" + ; + break;} +case 81: +#line 580 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{; + break;} +case 82: +#line 580 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{; + break;} +case 83: +#line 582 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 543 "/usr/share/bison.simple" yyvsp -= yylen; yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif - - YY_STACK_PRINT (yyss, yyssp); +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif *++yyvsp = yyval; +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ yyn = yyr1[yyn]; - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else - yystate = yydefgoto[yyn - YYNTOKENS]; + yystate = yydefgoto[yyn - YYNTBASE]; goto yynewstate; +yyerrlab: /* here on detecting error */ -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ { ++yynerrs; -#if YYERROR_VERBOSE + +#ifdef YYERROR_VERBOSE yyn = yypact[yystate]; - if (YYPACT_NINF < yyn && yyn < YYLAST) + if (yyn > YYFLAG && yyn < YYLAST) { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - const char* yyprefix; - char *yymsg; - int yyx; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 0; - - yyprefix = ", expecting "; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); - yycount += 1; - if (yycount == 5) - { - yysize = 0; - break; - } - } - yysize += (sizeof ("syntax error, unexpected ") - + yystrlen (yytname[yytype])); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); + strcpy(msg, "parse error"); - if (yycount < 5) + if (count < 5) { - yyprefix = ", expecting "; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) { - yyp = yystpcpy (yyp, yyprefix); - yyp = yystpcpy (yyp, yytname[yyx]); - yyprefix = " or "; + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; } } - yyerror (yymsg); - YYSTACK_FREE (yymsg); + yyerror(msg); + free(msg); } else - yyerror ("syntax error; also virtual memory exhausted"); + yyerror ("parse error; also virtual memory exceeded"); } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror("parse error"); } - + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + /* if just tried and failed to reuse lookahead token after an error, discard it. */ - if (yychar <= YYEOF) - { - /* If at end of input, pop the error token, - then the rest of the stack, then return failure. */ - if (yychar == YYEOF) - for (;;) - { - YYPOPSTACK; - if (yyssp == yyss) - YYABORT; - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - } - } - else - { - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; - } +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; } - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; + /* Else will try to reuse lookahead token + after shifting the error token. */ + yyerrstatus = 3; /* Each real token shifted decrements this */ -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: + goto yyerrhandle; -#ifdef __GNUC__ - /* Pacify GCC when the user code never invokes YYERROR and the label - yyerrorlab therefore never appears in user code. */ - if (0) - goto yyerrorlab; -#endif +yyerrdefault: /* current state does not do anything special for the error token. */ - yyvsp -= yylen; - yyssp -= yylen; - yystate = *yyssp; - goto yyerrlab1; +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif +yyerrpop: /* pop the current state because it cannot handle the error token */ -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif - for (;;) +#if YYDEBUG != 0 + if (yydebug) { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - YYPOPSTACK; - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; } + else if (yyn == 0) + goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; - YYDPRINTF ((stderr, "Shifting error token, ")); +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif *++yyvsp = yylval; - +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif yystate = yyn; goto yynewstate; + yyacceptlab: + /* YYACCEPT comes here. */ + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); +#endif + } + return 0; -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); + yyabortlab: + /* YYABORT comes here. */ + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); #endif - return yyresult; + } + return 1; } - - -#line 584 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" +#line 584 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" int yyerror(const char *ErrorMsg) { err() << "Error parsing: " << ErrorMsg << "\n"; exit(1); } - Index: llvm/utils/TableGen/FileParser.h diff -u llvm/utils/TableGen/FileParser.h:1.1 llvm/utils/TableGen/FileParser.h:1.2 --- llvm/utils/TableGen/FileParser.h:1.1 Sat Aug 27 13:50:39 2005 +++ llvm/utils/TableGen/FileParser.h Thu Sep 8 13:22:57 2005 @@ -1,83 +1,4 @@ -/* A Bison parser, made by GNU Bison 1.875c. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - INT = 258, - BIT = 259, - STRING = 260, - BITS = 261, - LIST = 262, - CODE = 263, - DAG = 264, - CLASS = 265, - DEF = 266, - FIELD = 267, - LET = 268, - IN = 269, - SHLTOK = 270, - SRATOK = 271, - SRLTOK = 272, - INTVAL = 273, - ID = 274, - VARNAME = 275, - STRVAL = 276, - CODEFRAGMENT = 277 - }; -#endif -#define INT 258 -#define BIT 259 -#define STRING 260 -#define BITS 261 -#define LIST 262 -#define CODE 263 -#define DAG 264 -#define CLASS 265 -#define DEF 266 -#define FIELD 267 -#define LET 268 -#define IN 269 -#define SHLTOK 270 -#define SRATOK 271 -#define SRLTOK 272 -#define INTVAL 273 -#define ID 274 -#define VARNAME 275 -#define STRVAL 276 -#define CODEFRAGMENT 277 - - - - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 189 "/proj/llvm/build/../llvm/utils/TableGen/FileParser.y" -typedef union YYSTYPE { +typedef union { std::string* StrVal; int IntVal; llvm::RecTy* Ty; @@ -89,14 +10,26 @@ std::vector* SubClassList; std::vector >* DagValueList; } YYSTYPE; -/* Line 1275 of yacc.c. */ -#line 94 "FileParser.tab.h" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE Filelval; - +#define INT 257 +#define BIT 258 +#define STRING 259 +#define BITS 260 +#define LIST 261 +#define CODE 262 +#define DAG 263 +#define CLASS 264 +#define DEF 265 +#define FIELD 266 +#define LET 267 +#define IN 268 +#define SHLTOK 269 +#define SRATOK 270 +#define SRLTOK 271 +#define INTVAL 272 +#define ID 273 +#define VARNAME 274 +#define STRVAL 275 +#define CODEFRAGMENT 276 +extern YYSTYPE Filelval; From lattner at cs.uiuc.edu Thu Sep 8 13:47:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 13:47:33 -0500 Subject: [llvm-commits] CVS: llvm/docs/TableGenFundamentals.html Message-ID: <200509081847.NAA28017@zion.cs.uiuc.edu> Changes in directory llvm/docs: TableGenFundamentals.html updated: 1.12 -> 1.13 --- Log message: new expression type --- Diffs of the changes: (+3 -1) TableGenFundamentals.html | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/docs/TableGenFundamentals.html diff -u llvm/docs/TableGenFundamentals.html:1.12 llvm/docs/TableGenFundamentals.html:1.13 --- llvm/docs/TableGenFundamentals.html:1.12 Wed Aug 4 17:00:05 2004 +++ llvm/docs/TableGenFundamentals.html Thu Sep 8 13:47:21 2005 @@ -309,6 +309,8 @@
  • value{17} - access to one bit of a value
  • value{15-17} - access to multiple bits of a value
  • DEF - reference to a record definition
  • +
  • CLASS<val list> - reference to a new anonymous definition of + CLASS with the specified template arguments.
  • X.Y - reference to the subfield of a value
  • list[4-7,17,2-3] - A slice of the 'list' list, including elements 4,5,6,7,17,2, and 3 from it. Elements may be included multiple times.
  • @@ -558,7 +560,7 @@ Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/08/04 22:00:05 $ + Last modified: $Date: 2005/09/08 18:47:21 $ From lattner at cs.uiuc.edu Thu Sep 8 13:47:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 13:47:55 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/AnonDefinitionOnDemand.td Message-ID: <200509081847.NAA28072@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: AnonDefinitionOnDemand.td added (r1.1) --- Log message: x and X should be structurally identical --- Diffs of the changes: (+12 -0) AnonDefinitionOnDemand.td | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/TableGen/AnonDefinitionOnDemand.td diff -c /dev/null llvm/test/Regression/TableGen/AnonDefinitionOnDemand.td:1.1 *** /dev/null Thu Sep 8 13:47:53 2005 --- llvm/test/Regression/TableGen/AnonDefinitionOnDemand.td Thu Sep 8 13:47:43 2005 *************** *** 0 **** --- 1,12 ---- + // RUN: tblgen < %s + + class foo { int THEVAL = X; } + def foo_imp : foo<1>; + + def x { + foo Y = foo_imp; // This works. + } + + def X { + foo Y = foo<1>; // This should work too, synthesizing a new foo<1>. + } From lattner at cs.uiuc.edu Thu Sep 8 13:48:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 13:48:34 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200509081848.NAA28108@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.34 -> 1.35 --- Log message: Add support for automatically created anonymous definitions. This implements Regression/TableGen/AnonDefinitionOnDemand.td --- Diffs of the changes: (+30 -1) FileParser.y | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletion(-) Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.34 llvm/utils/TableGen/FileParser.y:1.35 --- llvm/utils/TableGen/FileParser.y:1.34 Thu Sep 8 13:22:35 2005 +++ llvm/utils/TableGen/FileParser.y Thu Sep 8 13:48:23 2005 @@ -291,6 +291,34 @@ } delete $1; + } | ID '<' ValueListNE '>' { + // This is a CLASS expression. This is supposed to synthesize + // a new anonymous definition, deriving from CLASS with no + // body. + Record *Class = Records.getClass(*$1); + if (!Class) { + err() << "Expected a class, got '" << *$1 << "'!\n"; + exit(1); + } + delete $1; + + static unsigned AnonCounter = 0; + Record *OldRec = CurRec; // Save CurRec. + + // Create the new record, set it as CurRec temporarily. + CurRec = new Record("anonymous.val."+utostr(AnonCounter++)); + addSubClass(Class, *$3); // Add info about the subclass to CurRec. + delete $3; // Free up the template args. + + CurRec->resolveReferences(); + + Records.addDef(CurRec); + + // The result of the expression is a reference to the new record. + $$ = new DefInit(CurRec); + + // Restore the old CurRec + CurRec = OldRec; } | Value '{' BitList '}' { $$ = $1->convertInitializerBitRange(*$3); if ($$ == 0) { @@ -543,12 +571,13 @@ DefInst : DEF ObjectBody { $2->resolveReferences(); + // If ObjectBody has template arguments, it's an error. if (!$2->getTemplateArgs().empty()) { err() << "Def '" << $2->getName() << "' is not permitted to have template arguments!\n"; exit(1); } - // If ObjectBody has template arguments, it's an error. + // Ensure redefinition doesn't happen. if (Records.getDef($2->getName())) { err() << "Def '" << $2->getName() << "' already defined!\n"; exit(1); From lattner at cs.uiuc.edu Thu Sep 8 13:48:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 13:48:58 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.cpp Message-ID: <200509081848.NAA28166@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.cpp updated: 1.2 -> 1.3 --- Log message: regenerate --- Diffs of the changes: (+259 -224) FileParser.cpp | 476 +++++++++++++++++++++++++++++++-------------------------- 1 files changed, 259 insertions(+), 217 deletions(-) Index: llvm/utils/TableGen/FileParser.cpp diff -u llvm/utils/TableGen/FileParser.cpp:1.2 llvm/utils/TableGen/FileParser.cpp:1.3 --- llvm/utils/TableGen/FileParser.cpp:1.2 Thu Sep 8 13:22:57 2005 +++ llvm/utils/TableGen/FileParser.cpp Thu Sep 8 13:48:47 2005 @@ -230,7 +230,7 @@ -#define YYFINAL 152 +#define YYFINAL 155 #define YYFLAG -32768 #define YYNTBASE 38 @@ -271,13 +271,13 @@ static const short yyprhs[] = { 0, 0, 2, 4, 6, 11, 13, 18, 20, 22, 24, 25, 27, 28, 31, 33, 35, 37, 39, 43, 45, - 50, 54, 58, 63, 68, 75, 82, 89, 90, 93, - 96, 101, 102, 104, 106, 110, 113, 117, 123, 128, - 130, 131, 135, 136, 138, 140, 144, 149, 152, 159, - 160, 163, 165, 169, 171, 176, 178, 182, 183, 186, - 188, 192, 196, 197, 199, 201, 202, 203, 204, 211, - 214, 217, 219, 221, 226, 228, 232, 233, 238, 243, - 246, 248, 251 + 50, 55, 59, 63, 68, 73, 80, 87, 94, 95, + 98, 101, 106, 107, 109, 111, 115, 118, 122, 128, + 133, 135, 136, 140, 141, 143, 145, 149, 154, 157, + 164, 165, 168, 170, 174, 176, 181, 183, 187, 188, + 191, 193, 197, 201, 202, 204, 206, 207, 208, 209, + 216, 219, 222, 224, 226, 231, 233, 237, 238, 243, + 248, 251, 253, 256 }; static const short yyrhs[] = { 19, @@ -285,28 +285,28 @@ 3, 0, 7, 23, 39, 24, 0, 8, 0, 9, 0, 38, 0, 0, 12, 0, 0, 25, 42, 0, 18, 0, 21, 0, 22, 0, 26, 0, 27, 49, - 28, 0, 19, 0, 42, 27, 47, 28, 0, 29, - 49, 30, 0, 42, 31, 19, 0, 32, 19, 45, - 33, 0, 42, 29, 47, 30, 0, 15, 32, 42, - 34, 42, 33, 0, 16, 32, 42, 34, 42, 33, - 0, 17, 32, 42, 34, 42, 33, 0, 0, 35, - 20, 0, 42, 43, 0, 44, 34, 42, 43, 0, - 0, 44, 0, 18, 0, 18, 36, 18, 0, 18, - 18, 0, 46, 34, 18, 0, 46, 34, 18, 36, - 18, 0, 46, 34, 18, 18, 0, 46, 0, 0, - 27, 47, 28, 0, 0, 50, 0, 42, 0, 50, - 34, 42, 0, 40, 39, 19, 41, 0, 51, 37, - 0, 13, 19, 48, 25, 42, 37, 0, 0, 53, - 52, 0, 37, 0, 27, 53, 28, 0, 38, 0, - 38, 23, 50, 24, 0, 55, 0, 56, 34, 55, - 0, 0, 35, 56, 0, 51, 0, 58, 34, 51, - 0, 23, 58, 24, 0, 0, 59, 0, 19, 0, - 0, 0, 0, 61, 63, 60, 57, 64, 54, 0, - 10, 62, 0, 11, 62, 0, 65, 0, 66, 0, - 19, 48, 25, 42, 0, 68, 0, 69, 34, 68, - 0, 0, 13, 71, 69, 14, 0, 70, 27, 72, - 28, 0, 70, 67, 0, 67, 0, 72, 67, 0, - 72, 0 + 28, 0, 19, 0, 19, 23, 50, 24, 0, 42, + 27, 47, 28, 0, 29, 49, 30, 0, 42, 31, + 19, 0, 32, 19, 45, 33, 0, 42, 29, 47, + 30, 0, 15, 32, 42, 34, 42, 33, 0, 16, + 32, 42, 34, 42, 33, 0, 17, 32, 42, 34, + 42, 33, 0, 0, 35, 20, 0, 42, 43, 0, + 44, 34, 42, 43, 0, 0, 44, 0, 18, 0, + 18, 36, 18, 0, 18, 18, 0, 46, 34, 18, + 0, 46, 34, 18, 36, 18, 0, 46, 34, 18, + 18, 0, 46, 0, 0, 27, 47, 28, 0, 0, + 50, 0, 42, 0, 50, 34, 42, 0, 40, 39, + 19, 41, 0, 51, 37, 0, 13, 19, 48, 25, + 42, 37, 0, 0, 53, 52, 0, 37, 0, 27, + 53, 28, 0, 38, 0, 38, 23, 50, 24, 0, + 55, 0, 56, 34, 55, 0, 0, 35, 56, 0, + 51, 0, 58, 34, 51, 0, 23, 58, 24, 0, + 0, 59, 0, 19, 0, 0, 0, 0, 61, 63, + 60, 57, 64, 54, 0, 10, 62, 0, 11, 62, + 0, 65, 0, 66, 0, 19, 48, 25, 42, 0, + 68, 0, 69, 34, 68, 0, 0, 13, 71, 69, + 14, 0, 70, 27, 72, 28, 0, 70, 67, 0, + 67, 0, 72, 67, 0, 72, 0 }; #endif @@ -315,13 +315,13 @@ static const short yyrline[] = { 0, 223, 234, 236, 238, 240, 242, 244, 246, 248, 252, 252, 254, 254, 256, 258, 261, 264, 266, 279, 294, - 301, 304, 311, 319, 327, 333, 339, 347, 350, 354, - 359, 365, 368, 371, 374, 387, 401, 403, 416, 432, - 434, 434, 438, 440, 444, 447, 451, 461, 463, 469, - 469, 470, 470, 472, 474, 478, 483, 488, 491, 495, - 498, 503, 504, 504, 506, 506, 508, 515, 530, 535, - 543, 560, 560, 562, 567, 567, 570, 570, 573, 576, - 580, 580, 582 + 322, 329, 332, 339, 347, 355, 361, 367, 375, 378, + 382, 387, 393, 396, 399, 402, 415, 429, 431, 444, + 460, 462, 462, 466, 468, 472, 475, 479, 489, 491, + 497, 497, 498, 498, 500, 502, 506, 511, 516, 519, + 523, 526, 531, 532, 532, 534, 534, 536, 543, 558, + 563, 571, 589, 589, 591, 596, 596, 599, 599, 602, + 605, 609, 609, 611 }; #endif @@ -343,117 +343,119 @@ static const short yyr1[] = { 0, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 41, 41, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 43, 43, 44, - 44, 45, 45, 46, 46, 46, 46, 46, 46, 47, - 48, 48, 49, 49, 50, 50, 51, 52, 52, 53, - 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, - 58, 59, 60, 60, 61, 61, 63, 64, 62, 65, - 66, 67, 67, 68, 69, 69, 71, 70, 67, 67, - 72, 72, 73 + 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, + 44, 44, 45, 45, 46, 46, 46, 46, 46, 46, + 47, 48, 48, 49, 49, 50, 50, 51, 52, 52, + 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, + 58, 58, 59, 60, 60, 61, 61, 63, 64, 62, + 65, 66, 67, 67, 68, 69, 69, 71, 70, 67, + 67, 72, 72, 73 }; static const short yyr2[] = { 0, 1, 1, 1, 4, 1, 4, 1, 1, 1, 0, 1, 0, 2, 1, 1, 1, 1, 3, 1, 4, - 3, 3, 4, 4, 6, 6, 6, 0, 2, 2, - 4, 0, 1, 1, 3, 2, 3, 5, 4, 1, - 0, 3, 0, 1, 1, 3, 4, 2, 6, 0, - 2, 1, 3, 1, 4, 1, 3, 0, 2, 1, - 3, 3, 0, 1, 1, 0, 0, 0, 6, 2, - 2, 1, 1, 4, 1, 3, 0, 4, 4, 2, - 1, 2, 1 + 4, 3, 3, 4, 4, 6, 6, 6, 0, 2, + 2, 4, 0, 1, 1, 3, 2, 3, 5, 4, + 1, 0, 3, 0, 1, 1, 3, 4, 2, 6, + 0, 2, 1, 3, 1, 4, 1, 3, 0, 2, + 1, 3, 3, 0, 1, 1, 0, 0, 0, 6, + 2, 2, 1, 1, 4, 1, 3, 0, 4, 4, + 2, 1, 2, 1 }; static const short yydefact[] = { 0, - 66, 66, 77, 72, 73, 81, 0, 83, 65, 67, - 70, 71, 0, 0, 80, 82, 63, 41, 75, 0, - 0, 10, 64, 58, 0, 0, 78, 0, 79, 11, - 0, 60, 0, 0, 68, 34, 40, 0, 0, 76, + 67, 67, 78, 73, 74, 82, 0, 84, 66, 68, + 71, 72, 0, 0, 81, 83, 64, 42, 76, 0, + 0, 10, 65, 59, 0, 0, 79, 0, 80, 11, + 0, 61, 0, 0, 69, 35, 41, 0, 0, 77, 5, 3, 2, 0, 0, 7, 8, 1, 9, 0, - 62, 10, 54, 56, 59, 0, 36, 0, 0, 42, - 0, 0, 0, 14, 19, 15, 16, 17, 43, 43, - 0, 74, 0, 0, 12, 61, 0, 0, 50, 52, - 69, 35, 37, 0, 0, 0, 45, 0, 44, 0, - 32, 0, 0, 0, 0, 0, 0, 47, 0, 57, - 10, 39, 0, 0, 0, 0, 18, 0, 21, 28, - 33, 0, 0, 0, 22, 4, 6, 13, 55, 0, - 53, 0, 51, 38, 0, 0, 0, 46, 0, 30, - 0, 23, 20, 24, 41, 48, 0, 0, 0, 29, - 28, 0, 25, 26, 27, 31, 0, 0, 49, 0, - 0, 0 + 63, 10, 55, 57, 60, 0, 37, 0, 0, 43, + 0, 0, 0, 14, 19, 15, 16, 17, 44, 44, + 0, 75, 0, 0, 12, 62, 0, 0, 51, 53, + 70, 36, 38, 0, 0, 0, 0, 46, 0, 45, + 0, 33, 0, 0, 0, 0, 0, 0, 48, 0, + 58, 10, 40, 0, 0, 0, 0, 0, 18, 0, + 22, 29, 34, 0, 0, 0, 23, 4, 6, 13, + 56, 0, 54, 0, 52, 39, 0, 0, 0, 20, + 47, 0, 31, 0, 24, 21, 25, 42, 49, 0, + 0, 0, 30, 29, 0, 26, 27, 28, 32, 0, + 0, 50, 0, 0, 0 }; static const short yydefgoto[] = { 49, - 50, 31, 98, 87, 130, 111, 112, 37, 38, 26, - 88, 89, 32, 123, 101, 81, 54, 55, 35, 33, + 50, 31, 99, 88, 133, 113, 114, 37, 38, 26, + 89, 90, 32, 125, 102, 81, 54, 55, 35, 33, 23, 24, 10, 11, 17, 56, 4, 5, 6, 19, - 20, 7, 13, 8, 150 + 20, 7, 13, 8, 153 }; -static const short yypact[] = { 61, - -10, -10,-32768,-32768,-32768,-32768, 4, 61,-32768,-32768, --32768,-32768, -3, 61,-32768,-32768, 12, -7,-32768, -12, - -5, 24,-32768, 7, 38, 42,-32768, -3,-32768,-32768, - 56,-32768, 15, 54,-32768, -15, 49, 66, 11,-32768, --32768,-32768,-32768, 67, 75,-32768,-32768,-32768,-32768, 81, --32768, 24, 78,-32768, 70, 14,-32768, 88, 99,-32768, - 87, 89, 90,-32768,-32768,-32768,-32768,-32768, 11, 11, - 101, 26, 105, 56, 100,-32768, 11, 54,-32768,-32768, --32768,-32768, -11, 11, 11, 11, 26, 96, 92, 97, - 11, 38, 38, 109, 106, 107, 11,-32768, 20,-32768, - 6,-32768, 111, 62, 68, 76,-32768, 11,-32768, 50, - 98, 102, 108, 103,-32768,-32768,-32768, 26,-32768, 115, --32768, 104,-32768,-32768, 11, 11, 11, 26, 117,-32768, - 11,-32768,-32768,-32768, -7,-32768, 51, 82, 85,-32768, - 50, 113,-32768,-32768,-32768,-32768, 11, 39,-32768, 139, - 140,-32768 +static const short yypact[] = { 45, + -10, -10,-32768,-32768,-32768,-32768, 4, 45,-32768,-32768, +-32768,-32768, -3, 45,-32768,-32768, 12, -7,-32768, -12, + -5, 24,-32768, 39, 23, 25,-32768, -3,-32768,-32768, + 57,-32768, 15, 64,-32768, -15, 51, 58, 11,-32768, +-32768,-32768,-32768, 68, 70,-32768,-32768,-32768,-32768, 78, +-32768, 24, 80,-32768, 67, 17,-32768, 89, 91,-32768, + 94, 95, 96,-32768, 98,-32768,-32768,-32768, 11, 11, + 104, 93, 107, 57, 105,-32768, 11, 64,-32768,-32768, +-32768,-32768, -11, 11, 11, 11, 11, 93, 101, 97, + 102, 11, 23, 23, 114, 110, 111, 11,-32768, 18, +-32768, 6,-32768, 118, 53, 65, 71, 33,-32768, 11, +-32768, 46, 103, 106, 112, 108,-32768,-32768,-32768, 93, +-32768, 122,-32768, 109,-32768,-32768, 11, 11, 11,-32768, + 93, 123,-32768, 11,-32768,-32768,-32768, -7,-32768, 77, + 85, 86,-32768, 46, 117,-32768,-32768,-32768,-32768, 11, + 41,-32768, 144, 145,-32768 }; static const short yypgoto[] = { -30, - 69,-32768,-32768, -39, 1,-32768,-32768,-32768, -80, 9, - 77, 71, -51,-32768,-32768,-32768, 72,-32768,-32768,-32768, --32768,-32768,-32768, 143,-32768,-32768,-32768,-32768, 3, 118, --32768,-32768,-32768, 135,-32768 + 73,-32768,-32768, -39, 5,-32768,-32768,-32768, -81, 10, + 81, -8, -51,-32768,-32768,-32768, 72,-32768,-32768,-32768, +-32768,-32768,-32768, 150,-32768,-32768,-32768,-32768, 3, 125, +-32768,-32768,-32768, 140,-32768 }; -#define YYLAST 150 +#define YYLAST 154 static const short yytable[] = { 72, - 76, 27, 57, 53, 1, 2, 102, 3, 9, 15, - 16, 113, 114, 1, 2, 18, 3, 30, 120, 25, - 58, 28, 29, 16, 103, 61, 62, 63, 64, 65, - 14, 66, 67, 121, 22, 30, 68, 69, 51, 70, - 79, 34, 71, 119, 104, 105, 106, 53, 52, 122, - 80, 110, 92, 108, 93, 36, 94, 118, 41, 42, - 43, 44, 45, 46, 47, 92, 39, 93, 128, 94, - 1, 2, 48, 3, 48, 149, 92, 92, 93, 93, - 94, 94, 59, 143, 129, 137, 138, 139, 92, 73, - 93, 141, 94, 60, 92, 125, 93, 74, 94, 75, - 77, 126, 92, 78, 93, 82, 94, 148, 92, 127, - 93, 92, 94, 93, 144, 94, 83, 145, 84, 91, - 85, 86, 95, 107, 97, 108, 109, 115, 124, 116, - 117, 131, 134, 135, 132, 133, 140, 147, 151, 152, - 136, 146, 96, 142, 12, 40, 90, 99, 21, 100 + 76, 27, 57, 53, 1, 2, 103, 3, 9, 15, + 16, 115, 116, 1, 2, 18, 3, 30, 122, 25, + 58, 28, 29, 16, 104, 61, 62, 63, 64, 65, + 14, 66, 67, 123, 22, 30, 68, 69, 51, 70, + 36, 121, 71, 79, 105, 106, 107, 53, 52, 39, + 124, 110, 112, 80, 1, 2, 130, 3, 120, 41, + 42, 43, 44, 45, 46, 47, 110, 93, 100, 94, + 131, 95, 93, 34, 94, 48, 95, 152, 108, 93, + 132, 94, 48, 95, 59, 60, 127, 140, 141, 142, + 73, 93, 74, 94, 144, 95, 75, 93, 128, 94, + 78, 95, 77, 93, 129, 94, 82, 95, 83, 146, + 151, 93, 93, 94, 94, 95, 95, 147, 148, 93, + 87, 94, 92, 95, 96, 84, 85, 86, 109, 98, + 110, 111, 117, 118, 119, 126, 134, 137, 135, 136, + 138, 150, 143, 154, 155, 139, 97, 145, 149, 101, + 91, 12, 40, 21 }; static const short yycheck[] = { 39, 52, 14, 18, 34, 10, 11, 18, 13, 19, 7, - 8, 92, 93, 10, 11, 19, 13, 12, 13, 27, + 8, 93, 94, 10, 11, 19, 13, 12, 13, 27, 36, 34, 28, 21, 36, 15, 16, 17, 18, 19, 27, 21, 22, 28, 23, 12, 26, 27, 24, 29, - 27, 35, 32, 24, 84, 85, 86, 78, 34, 101, - 37, 91, 27, 34, 29, 18, 31, 97, 3, 4, - 5, 6, 7, 8, 9, 27, 25, 29, 108, 31, - 10, 11, 19, 13, 19, 37, 27, 27, 29, 29, - 31, 31, 34, 33, 35, 125, 126, 127, 27, 23, - 29, 131, 31, 28, 27, 34, 29, 23, 31, 19, - 23, 34, 27, 34, 29, 18, 31, 147, 27, 34, - 29, 27, 31, 29, 33, 31, 18, 33, 32, 19, - 32, 32, 18, 28, 25, 34, 30, 19, 18, 24, - 24, 34, 30, 19, 33, 28, 20, 25, 0, 0, - 37, 141, 74, 135, 2, 28, 70, 77, 14, 78 + 18, 24, 32, 27, 84, 85, 86, 78, 34, 25, + 102, 34, 92, 37, 10, 11, 24, 13, 98, 3, + 4, 5, 6, 7, 8, 9, 34, 27, 77, 29, + 110, 31, 27, 35, 29, 19, 31, 37, 87, 27, + 35, 29, 19, 31, 34, 28, 34, 127, 128, 129, + 23, 27, 23, 29, 134, 31, 19, 27, 34, 29, + 34, 31, 23, 27, 34, 29, 18, 31, 18, 33, + 150, 27, 27, 29, 29, 31, 31, 33, 33, 27, + 23, 29, 19, 31, 18, 32, 32, 32, 28, 25, + 34, 30, 19, 24, 24, 18, 34, 30, 33, 28, + 19, 25, 20, 0, 0, 37, 74, 138, 144, 78, + 70, 2, 28, 14 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/bison.simple" @@ -1138,6 +1140,38 @@ case 20: #line 294 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { + // This is a CLASS expression. This is supposed to synthesize + // a new anonymous definition, deriving from CLASS with no + // body. + Record *Class = Records.getClass(*yyvsp[-3].StrVal); + if (!Class) { + err() << "Expected a class, got '" << *yyvsp[-3].StrVal << "'!\n"; + exit(1); + } + delete yyvsp[-3].StrVal; + + static unsigned AnonCounter = 0; + Record *OldRec = CurRec; // Save CurRec. + + // Create the new record, set it as CurRec temporarily. + CurRec = new Record("anonymous.val."+utostr(AnonCounter++)); + addSubClass(Class, *yyvsp[-1].FieldList); // Add info about the subclass to CurRec. + delete yyvsp[-1].FieldList; // Free up the template args. + + CurRec->resolveReferences(); + + Records.addDef(CurRec); + + // The result of the expression is a reference to the new record. + yyval.Initializer = new DefInit(CurRec); + + // Restore the old CurRec + CurRec = OldRec; + ; + break;} +case 21: +#line 322 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{ yyval.Initializer = yyvsp[-3].Initializer->convertInitializerBitRange(*yyvsp[-1].BitList); if (yyval.Initializer == 0) { err() << "Invalid bit range for value '" << *yyvsp[-3].Initializer << "'!\n"; @@ -1146,15 +1180,15 @@ delete yyvsp[-1].BitList; ; break;} -case 21: -#line 301 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 22: +#line 329 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.Initializer = new ListInit(*yyvsp[-1].FieldList); delete yyvsp[-1].FieldList; ; break;} -case 22: -#line 304 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 23: +#line 332 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { if (!yyvsp[-2].Initializer->getFieldType(*yyvsp[0].StrVal)) { err() << "Cannot access field '" << *yyvsp[0].StrVal << "' of value '" << *yyvsp[-2].Initializer << "!\n"; @@ -1164,8 +1198,8 @@ delete yyvsp[0].StrVal; ; break;} -case 23: -#line 311 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 24: +#line 339 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { Record *D = Records.getDef(*yyvsp[-2].StrVal); if (D == 0) { @@ -1176,8 +1210,8 @@ delete yyvsp[-2].StrVal; delete yyvsp[-1].DagValueList; ; break;} -case 24: -#line 319 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 25: +#line 347 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { std::reverse(yyvsp[-1].BitList->begin(), yyvsp[-1].BitList->end()); yyval.Initializer = yyvsp[-3].Initializer->convertInitListSlice(*yyvsp[-1].BitList); @@ -1188,8 +1222,8 @@ delete yyvsp[-1].BitList; ; break;} -case 25: -#line 327 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 26: +#line 355 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SHL, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { @@ -1198,8 +1232,8 @@ } ; break;} -case 26: -#line 333 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 27: +#line 361 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SRA, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { @@ -1208,8 +1242,8 @@ } ; break;} -case 27: -#line 339 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 28: +#line 367 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.Initializer = yyvsp[-3].Initializer->getBinaryOp(Init::SRL, yyvsp[-1].Initializer); if (yyval.Initializer == 0) { @@ -1218,53 +1252,53 @@ } ; break;} -case 28: -#line 347 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 29: +#line 375 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.StrVal = new std::string(); ; break;} -case 29: -#line 350 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 30: +#line 378 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.StrVal = yyvsp[0].StrVal; ; break;} -case 30: -#line 354 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 31: +#line 382 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.DagValueList = new std::vector >(); yyval.DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); delete yyvsp[0].StrVal; ; break;} -case 31: -#line 359 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 32: +#line 387 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyvsp[-3].DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); delete yyvsp[0].StrVal; yyval.DagValueList = yyvsp[-3].DagValueList; ; break;} -case 32: -#line 365 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 33: +#line 393 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.DagValueList = new std::vector >(); ; break;} -case 33: -#line 368 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 34: +#line 396 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.DagValueList = yyvsp[0].DagValueList; ; break;} -case 34: -#line 371 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 35: +#line 399 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.BitList = new std::vector(); yyval.BitList->push_back(yyvsp[0].IntVal); ; break;} -case 35: -#line 374 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 36: +#line 402 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; @@ -1280,8 +1314,8 @@ } ; break;} -case 36: -#line 387 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 37: +#line 415 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyvsp[0].IntVal = -yyvsp[0].IntVal; if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { @@ -1298,14 +1332,14 @@ } ; break;} -case 37: -#line 401 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 38: +#line 429 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { (yyval.BitList=yyvsp[-2].BitList)->push_back(yyvsp[0].IntVal); ; break;} -case 38: -#line 403 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 39: +#line 431 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; @@ -1321,8 +1355,8 @@ } ; break;} -case 39: -#line 416 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 40: +#line 444 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyvsp[0].IntVal = -yyvsp[0].IntVal; if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { @@ -1339,45 +1373,45 @@ } ; break;} -case 40: -#line 432 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 41: +#line 460 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.BitList = yyvsp[0].BitList; std::reverse(yyvsp[0].BitList->begin(), yyvsp[0].BitList->end()); ; break;} -case 41: -#line 434 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 42: +#line 462 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.BitList = 0; ; break;} -case 42: -#line 434 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 43: +#line 462 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.BitList = yyvsp[-1].BitList; ; break;} -case 43: -#line 438 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 44: +#line 466 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.FieldList = new std::vector(); ; break;} -case 44: -#line 440 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 45: +#line 468 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.FieldList = yyvsp[0].FieldList; ; break;} -case 45: -#line 444 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 46: +#line 472 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.FieldList = new std::vector(); yyval.FieldList->push_back(yyvsp[0].Initializer); ; break;} -case 46: -#line 447 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 47: +#line 475 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { (yyval.FieldList = yyvsp[-2].FieldList)->push_back(yyvsp[0].Initializer); ; break;} -case 47: -#line 451 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 48: +#line 479 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { std::string DecName = *yyvsp[-1].StrVal; if (ParsingTemplateArgs) @@ -1388,87 +1422,87 @@ yyval.StrVal = new std::string(DecName); ; break;} -case 48: -#line 461 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 49: +#line 489 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { delete yyvsp[-1].StrVal; ; break;} -case 49: -#line 463 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 50: +#line 491 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { setValue(*yyvsp[-4].StrVal, yyvsp[-3].BitList, yyvsp[-1].Initializer); delete yyvsp[-4].StrVal; delete yyvsp[-3].BitList; ; break;} -case 54: -#line 472 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 55: +#line 500 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.SubClassRef = new SubClassRefTy(yyvsp[0].Rec, new std::vector()); ; break;} -case 55: -#line 474 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 56: +#line 502 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.SubClassRef = new SubClassRefTy(yyvsp[-3].Rec, yyvsp[-1].FieldList); ; break;} -case 56: -#line 478 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 57: +#line 506 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.SubClassList = new std::vector(); yyval.SubClassList->push_back(*yyvsp[0].SubClassRef); delete yyvsp[0].SubClassRef; ; break;} -case 57: -#line 483 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 58: +#line 511 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { (yyval.SubClassList=yyvsp[-2].SubClassList)->push_back(*yyvsp[0].SubClassRef); delete yyvsp[0].SubClassRef; ; break;} -case 58: -#line 488 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 59: +#line 516 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.SubClassList = new std::vector(); ; break;} -case 59: -#line 491 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 60: +#line 519 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.SubClassList = yyvsp[0].SubClassList; ; break;} -case 60: -#line 495 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 61: +#line 523 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { CurRec->addTemplateArg(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; ; break;} -case 61: -#line 498 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 62: +#line 526 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { CurRec->addTemplateArg(*yyvsp[0].StrVal); delete yyvsp[0].StrVal; ; break;} -case 62: -#line 503 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 63: +#line 531 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" {; break;} -case 65: -#line 506 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 66: +#line 534 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.StrVal = yyvsp[0].StrVal; ; break;} -case 66: -#line 506 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 67: +#line 534 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.StrVal = new std::string(); ; break;} -case 67: -#line 508 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 68: +#line 536 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { static unsigned AnonCounter = 0; if (yyvsp[0].StrVal->empty()) @@ -1478,8 +1512,8 @@ ParsingTemplateArgs = true; ; break;} -case 68: -#line 515 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 69: +#line 543 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { ParsingTemplateArgs = false; for (unsigned i = 0, e = yyvsp[0].SubClassList->size(); i != e; ++i) { @@ -1497,15 +1531,15 @@ LetStack[i][j].Value); ; break;} -case 69: -#line 530 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 70: +#line 558 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyval.Rec = CurRec; CurRec = 0; ; break;} -case 70: -#line 535 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 71: +#line 563 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { if (Records.getClass(yyvsp[0].Rec->getName())) { err() << "Class '" << yyvsp[0].Rec->getName() << "' already defined!\n"; @@ -1514,17 +1548,18 @@ Records.addClass(yyval.Rec = yyvsp[0].Rec); ; break;} -case 71: -#line 543 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 72: +#line 571 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { yyvsp[0].Rec->resolveReferences(); + // If ObjectBody has template arguments, it's an error. if (!yyvsp[0].Rec->getTemplateArgs().empty()) { err() << "Def '" << yyvsp[0].Rec->getName() << "' is not permitted to have template arguments!\n"; exit(1); } - // If ObjectBody has template arguments, it's an error. + // Ensure redefinition doesn't happen. if (Records.getDef(yyvsp[0].Rec->getName())) { err() << "Def '" << yyvsp[0].Rec->getName() << "' already defined!\n"; exit(1); @@ -1532,39 +1567,39 @@ Records.addDef(yyval.Rec = yyvsp[0].Rec); ; break;} -case 74: -#line 562 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 75: +#line 591 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { LetStack.back().push_back(LetRecord(*yyvsp[-3].StrVal, yyvsp[-2].BitList, yyvsp[0].Initializer)); delete yyvsp[-3].StrVal; delete yyvsp[-2].BitList; ; break;} -case 77: -#line 570 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 78: +#line 599 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { LetStack.push_back(std::vector()); ; break;} -case 79: -#line 573 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 80: +#line 602 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { LetStack.pop_back(); ; break;} -case 80: -#line 576 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +case 81: +#line 605 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" { LetStack.pop_back(); ; break;} -case 81: -#line 580 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{; - break;} case 82: -#line 580 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +#line 609 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" {; break;} case 83: -#line 582 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +#line 609 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +{; + break;} +case 84: +#line 611 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" {; break;} } @@ -1789,7 +1824,7 @@ } return 1; } -#line 584 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" +#line 613 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" int yyerror(const char *ErrorMsg) { From lattner at cs.uiuc.edu Thu Sep 8 14:47:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 14:47:40 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.cpp Message-ID: <200509081947.OAA12376@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.cpp updated: 1.3 -> 1.4 --- Log message: Fix indentation --- Diffs of the changes: (+1 -1) FileParser.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/FileParser.cpp diff -u llvm/utils/TableGen/FileParser.cpp:1.3 llvm/utils/TableGen/FileParser.cpp:1.4 --- llvm/utils/TableGen/FileParser.cpp:1.3 Thu Sep 8 13:48:47 2005 +++ llvm/utils/TableGen/FileParser.cpp Thu Sep 8 14:47:28 2005 @@ -1158,7 +1158,7 @@ addSubClass(Class, *yyvsp[-1].FieldList); // Add info about the subclass to CurRec. delete yyvsp[-1].FieldList; // Free up the template args. - CurRec->resolveReferences(); + CurRec->resolveReferences(); Records.addDef(CurRec); From lattner at cs.uiuc.edu Thu Sep 8 14:50:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 14:50:52 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509081950.OAA14352@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.93 -> 1.94 --- Log message: Add a bunch of stuff needed for node type inference. Move 'BLR' down with the rest of the instructions, add comment markers to seperate portions of the file into logical parts --- Diffs of the changes: (+114 -21) PowerPCInstrInfo.td | 135 +++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 114 insertions(+), 21 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.93 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.94 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.93 Thu Sep 8 12:40:49 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 8 14:50:41 2005 @@ -14,28 +14,102 @@ include "PowerPCInstrFormats.td" -class SDNode { +//===----------------------------------------------------------------------===// +// Selection DAG Type Constraint definitions. +// +// Note that the semantics of these constraints are hard coded into tblgen. +// + +class SDTypeConstraint { + int OperandNum = opnum; +} + +// SDTCisVT - The specified operand has exactly this VT. +class SDTCisVT : SDTypeConstraint { + ValueType VT = vt; +} + +// SDTCisInt - The specified operand is has integer type. +class SDTCisInt : SDTypeConstraint; + +// SDTCisFP - The specified operand is has floating point type. +class SDTCisFP : SDTypeConstraint; + +// SDTCisSameAs - The two specified operands have identical types. +class SDTCisSameAs : SDTypeConstraint { + int OtherOperandNum = OtherOp; +} + +// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is +// smaller than the 'Other' operand. +class SDTCisVTSmallerThanOp : SDTypeConstraint { + int OtherOperandNum = OtherOp; +} + +//===----------------------------------------------------------------------===// +// Selection DAG Type Profile definitions. +// +// These use the constraints defined above to describe the type requirements of +// the various nodes. These are not hard coded into tblgen, allowing targets to +// add their own if needed. +// + +// SDTypeProfile - This profile describes the type requirements of a Selection +// DAG node. +class SDTypeProfile constraints> { + int NumResults = numresults; + int NumOperands = numoperands; + list Constraints = constraints; +} + +// Builtin profiles. +def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. +def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt' +def SDTBinOp : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>]>; +def SDTIntBinOp : SDTypeProfile<1, 2, [ // and, or, xor, udiv, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> +]>; +def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz + SDTCisSameAs<0, 1>, SDTCisInt<0> +]>; +def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg + SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, + SDTCisVTSmallerThanOp<2, 1> +]>; + + +//===----------------------------------------------------------------------===// +// Selection DAG Node definitions. +// +class SDNode { string Opcode = opcode; string SDClass = sdclass; + SDTypeProfile TypeProfile = typeprof; } def set; def node; -def imm : SDNode<"ISD::Constant", "ConstantSDNode">; -def vt : SDNode<"ISD::VALUETYPE", "VTSDNode">; -def and : SDNode<"ISD::AND">; -def or : SDNode<"ISD::OR">; -def xor : SDNode<"ISD::XOR">; -def add : SDNode<"ISD::ADD">; -def sub : SDNode<"ISD::SUB">; -def mul : SDNode<"ISD::MUL">; -def sdiv : SDNode<"ISD::SDIV">; -def udiv : SDNode<"ISD::UDIV">; -def mulhs : SDNode<"ISD::MULHS">; -def mulhu : SDNode<"ISD::MULHU">; -def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG">; -def ctlz : SDNode<"ISD::CTLZ">; +def imm : SDNode<"ISD::Constant" , SDTImm , "ConstantSDNode">; +def vt : SDNode<"ISD::VALUETYPE" , SDTVT , "VTSDNode">; +def and : SDNode<"ISD::AND" , SDTIntBinOp>; +def or : SDNode<"ISD::OR" , SDTIntBinOp>; +def xor : SDNode<"ISD::XOR" , SDTIntBinOp>; +def add : SDNode<"ISD::ADD" , SDTBinOp>; +def sub : SDNode<"ISD::SUB" , SDTBinOp>; +def mul : SDNode<"ISD::MUL" , SDTBinOp>; +def sdiv : SDNode<"ISD::SDIV" , SDTBinOp>; +def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; +def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp>; +def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp>; +def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; +def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; + + +//===----------------------------------------------------------------------===// +// Selection DAG Pattern Fragments. +// /// PatFrag - Represents a pattern fragment. This can match something on the /// DAG, frame a single node to multiply nested other fragments. @@ -65,7 +139,10 @@ def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; -// PowerPC-Specific predicates. + + +//===----------------------------------------------------------------------===// +// PowerPC specific pattern fragments. def immSExt16 : PatLeaf<(imm), [{ // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended @@ -96,6 +173,11 @@ Subtarget_PPC64>; */ + + +//===----------------------------------------------------------------------===// +// PowerPC Flag Definitions. + class isPPC64 { bit PPC64 = 1; } class isVMX { bit VMX = 1; } class isDOT { @@ -103,11 +185,10 @@ bit RC = 1; } -let isTerminator = 1 in { - let isReturn = 1 in - def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr">; - def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr">; -} + + +//===----------------------------------------------------------------------===// +// PowerPC Operand Definitions. def u5imm : Operand { let PrintMethod = "printU5ImmOperand"; @@ -137,8 +218,14 @@ let PrintMethod = "printcrbitm"; } + + +//===----------------------------------------------------------------------===// +// PowerPC Instruction Definitions. + // Pseudo-instructions: def PHI : Pseudo<(ops variable_ops), "; PHI">; + let isLoad = 1 in { def ADJCALLSTACKDOWN : Pseudo<(ops u16imm), "; ADJCALLSTACKDOWN">; def ADJCALLSTACKUP : Pseudo<(ops u16imm), "; ADJCALLSTACKUP">; @@ -156,6 +243,12 @@ } +let isTerminator = 1 in { + let isReturn = 1 in + def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr">; + def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr">; +} + let Defs = [LR] in def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label">; From natebegeman at mac.com Thu Sep 8 15:18:22 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 8 Sep 2005 15:18:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp SelectionDAG.cpp Message-ID: <200509082018.PAA22079@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.8 -> 1.9 SelectionDAG.cpp updated: 1.188 -> 1.189 --- Log message: Move yet more folds over to the dag combiner from sd.cpp --- Diffs of the changes: (+68 -12) DAGCombiner.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++-------- SelectionDAG.cpp | 11 +++++++- 2 files changed, 68 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.8 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.9 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.8 Wed Sep 7 18:25:52 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Sep 8 15:18:10 2005 @@ -355,16 +355,20 @@ // fold (add x, 0) -> x if (N1C && N1C->isNullValue()) return N0; - // fold (add (add x, c1), c2) -> (add x, c1+c2) - if (N1C && N0.getOpcode() == ISD::ADD && - N0.getOperand(1).getOpcode() == ISD::Constant) - return DAG.getNode(ISD::ADD, VT, N0.getOperand(0), - DAG.getConstant(N1C->getValue() + - cast(N0.getOperand(1))->getValue(), - VT)); // fold floating point (add c1, c2) -> c1+c2 if (N0CFP && N1CFP) return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), VT); + // fold (add (add x, c1), c2) -> (add x, c1+c2) + if (N1C && N0.getOpcode() == ISD::ADD) { + ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); + if (N00C) + return DAG.getNode(ISD::ADD, VT, N0.getOperand(1), + DAG.getConstant(N1C->getValue()+N00C->getValue(), VT)); + if (N01C) + return DAG.getNode(ISD::ADD, VT, N0.getOperand(0), + DAG.getConstant(N1C->getValue()+N01C->getValue(), VT)); + } // fold (A + (-B)) -> A-B if (N1.getOpcode() == ISD::FNEG) return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(0)); @@ -426,6 +430,7 @@ ConstantSDNode *N1C = dyn_cast(N1); ConstantFPSDNode *N0CFP = dyn_cast(N0); ConstantFPSDNode *N1CFP = dyn_cast(N1); + MVT::ValueType VT = N0.getValueType(); // fold (mul c1, c2) -> c1*c2 if (N0C && N1C) @@ -448,6 +453,17 @@ return DAG.getNode(ISD::SHL, N->getValueType(0), N0, DAG.getConstant(Log2_64(N1C->getValue()), TLI.getShiftAmountTy())); + // fold (mul (mul x, c1), c2) -> (mul x, c1*c2) + if (N1C && N0.getOpcode() == ISD::MUL) { + ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); + if (N00C) + return DAG.getNode(ISD::MUL, VT, N0.getOperand(1), + DAG.getConstant(N1C->getValue()*N00C->getValue(), VT)); + if (N01C) + return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), + DAG.getConstant(N1C->getValue()*N01C->getValue(), VT)); + } // fold floating point (mul c1, c2) -> c1*c2 if (N0CFP && N1CFP) return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(), @@ -581,6 +597,17 @@ if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)), TLI)) return N0; + // fold (and (and x, c1), c2) -> (and x, c1^c2) + if (N1C && N0.getOpcode() == ISD::AND) { + ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); + if (N00C) + return DAG.getNode(ISD::AND, VT, N0.getOperand(1), + DAG.getConstant(N1C->getValue()&N00C->getValue(), VT)); + if (N01C) + return DAG.getNode(ISD::AND, VT, N0.getOperand(0), + DAG.getConstant(N1C->getValue()&N01C->getValue(), VT)); + } // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { unsigned ExtendBits = @@ -623,6 +650,17 @@ if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)), TLI)) return N1; + // fold (or (or x, c1), c2) -> (or x, c1|c2) + if (N1C && N0.getOpcode() == ISD::OR) { + ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); + if (N00C) + return DAG.getNode(ISD::OR, VT, N0.getOperand(1), + DAG.getConstant(N1C->getValue()|N00C->getValue(), VT)); + if (N01C) + return DAG.getNode(ISD::OR, VT, N0.getOperand(0), + DAG.getConstant(N1C->getValue()|N01C->getValue(), VT)); + } return SDOperand(); } @@ -681,6 +719,20 @@ return DAG.getNode(NewOpcode, VT, LHS, RHS); } } + // fold (xor (xor x, c1), c2) -> (xor x, c1^c2) + if (N1C && N0.getOpcode() == ISD::XOR) { + ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); + if (N00C) + return DAG.getNode(ISD::XOR, VT, N0.getOperand(1), + DAG.getConstant(N1C->getValue()^N00C->getValue(), VT)); + if (N01C) + return DAG.getNode(ISD::XOR, VT, N0.getOperand(0), + DAG.getConstant(N1C->getValue()^N01C->getValue(), VT)); + } + // fold (xor x, x) -> 0 + if (N0 == N1) + return DAG.getConstant(0, VT); return SDOperand(); } @@ -1003,9 +1055,6 @@ MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); ConstantFPSDNode *N0CFP = dyn_cast(N0); - // noop fp_round_inreg - if (EVT == VT) - return N0; // fold (fp_round_inreg c1fp) -> c1fp if (N0CFP) { SDOperand Round = DAG.getConstantFP(N0CFP->getValue(), EVT); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.188 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.189 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.188 Wed Sep 7 18:25:52 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Sep 8 15:18:10 2005 @@ -1480,13 +1480,13 @@ } break; } - } // Reassociate ((X op C1) op C2) if possible. if (N1.getOpcode() == Opcode && isAssociativeBinOp(Opcode)) if (ConstantSDNode *N3C = dyn_cast(N1.Val->getOperand(1))) return getNode(Opcode, VT, N1.Val->getOperand(0), getNode(Opcode, VT, N2, N1.Val->getOperand(1))); + } } ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); @@ -1597,9 +1597,12 @@ N1.getOperand(0), N2.getOperand(0))); break; case ISD::XOR: + if (!CombinerEnabled) { if (N1 == N2) return getConstant(0, VT); // xor X, Y -> 0 + } break; case ISD::ADD: + if (!CombinerEnabled) { if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B return getNode(ISD::SUB, VT, N1, N2.getOperand(0)); if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A @@ -1613,8 +1616,10 @@ if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1) && !MVT::isFloatingPoint(N2.getValueType())) return N2.Val->getOperand(0); // A+(B-A) -> B + } break; case ISD::SUB: + if (!CombinerEnabled) { if (N1.getOpcode() == ISD::ADD) { if (N1.Val->getOperand(0) == N2 && !MVT::isFloatingPoint(N2.getValueType())) @@ -1625,6 +1630,7 @@ } if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B return getNode(ISD::ADD, VT, N1, N2.getOperand(0)); + } break; case ISD::FP_ROUND_INREG: if (cast(N2)->getVT() == VT) return N1; // Not actually rounding. @@ -1632,7 +1638,7 @@ case ISD::SIGN_EXTEND_INREG: { MVT::ValueType EVT = cast(N2)->getVT(); if (EVT == VT) return N1; // Not actually extending - + if (!CombinerEnabled) { // If we are sign extending an extension, use the original source. if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG || N1.getOpcode() == ISD::AssertSext) @@ -1660,6 +1666,7 @@ if ((Mask & (~0ULL << (NumBits-1))) == 0) return N1; } + } break; } From lattner at cs.uiuc.edu Thu Sep 8 16:03:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 16:03:12 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509082103.QAA24407@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.2 -> 1.3 DAGISelEmitter.h updated: 1.2 -> 1.3 --- Log message: start parsing SDNode info records --- Diffs of the changes: (+39 -0) DAGISelEmitter.cpp | 17 +++++++++++++++++ DAGISelEmitter.h | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.2 llvm/utils/TableGen/DAGISelEmitter.cpp:1.3 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.2 Thu Sep 8 12:45:12 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 16:03:01 2005 @@ -18,6 +18,13 @@ #include using namespace llvm; +//===----------------------------------------------------------------------===// +// SDNodeInfo implementation +// +SDNodeInfo::SDNodeInfo(Record *R) : Def(R) { + EnumName = R->getValueAsString("Opcode"); + SDClassName = R->getValueAsString("SDClass"); +} //===----------------------------------------------------------------------===// // TreePatternNode implementation @@ -349,6 +356,15 @@ // DAGISelEmitter implementation // +// Parse all of the SDNode definitions for the target, populating SDNodes. +void DAGISelEmitter::ParseNodeInfo() { + std::vector Nodes = Records.getAllDerivedDefinitions("SDNode"); + while (!Nodes.empty()) { + SDNodes.insert(std::make_pair(Nodes.back(), Nodes.back())); + Nodes.pop_back(); + } +} + /// ParseAndResolvePatternFragments - Parse all of the PatFrag definitions in /// the .td file, building up the PatternFragments map. After we've collected /// them all, inline fragments together as necessary, so that there are no @@ -458,6 +474,7 @@ EmitSourceFileHeader("DAG Instruction Selector for the " + Target.getName() + " target", OS); + ParseNodeInfo(); ParseAndResolvePatternFragments(OS); ParseAndResolveInstructions(); Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.2 llvm/utils/TableGen/DAGISelEmitter.h:1.3 --- llvm/utils/TableGen/DAGISelEmitter.h:1.2 Wed Sep 7 18:44:43 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Sep 8 16:03:01 2005 @@ -23,6 +23,21 @@ class DagInit; class TreePattern; class DAGISelEmitter; + + /// SDNodeInfo - One of these records is created for each SDNode instance in + /// the target .td file. This represents the various dag nodes we will be + /// processing. + class SDNodeInfo { + Record *Def; + std::string EnumName; + std::string SDClassName; + public: + SDNodeInfo(Record *R); // Parse the specified record. + + Record *getRecord() const { return Def; } + const std::string &getEnumName() const { return EnumName; } + const std::string &getSDClassName() const { return SDClassName; } + }; /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped /// patterns), and as such should be ref counted. We currently just leak all @@ -181,6 +196,7 @@ RecordKeeper &Records; CodeGenTarget Target; + std::map SDNodes; std::map PatternFragments; std::vector Instructions; public: @@ -188,6 +204,11 @@ // run - Output the isel, returning true on failure. void run(std::ostream &OS); + + const SDNodeInfo &getSDNodeInfo(Record *R) const { + assert(SDNodes.count(R) && "Unknown node!"); + return SDNodes.find(R)->second; + } TreePattern *getPatternFragment(Record *R) const { assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); @@ -195,6 +216,7 @@ } private: + void ParseNodeInfo(); void ParseAndResolvePatternFragments(std::ostream &OS); void ParseAndResolveInstructions(); void EmitInstructionSelector(std::ostream &OS); From lattner at cs.uiuc.edu Thu Sep 8 16:04:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 16:04:57 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509082104.QAA24476@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.3 -> 1.4 --- Log message: use node info in the one place we currently use it --- Diffs of the changes: (+1 -1) DAGISelEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.3 llvm/utils/TableGen/DAGISelEmitter.cpp:1.4 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.3 Thu Sep 8 16:03:01 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 16:04:46 2005 @@ -391,7 +391,7 @@ if (!CI->getValue().empty()) { assert(!P->getTrees()[0]->isLeaf() && "Can't be a leaf!"); std::string ClassName = - P->getTrees()[0]->getOperator()->getValueAsString("SDClass"); + getSDNodeInfo(P->getTrees()[0]->getOperator()).getSDClassName(); const char *C2 = ClassName == "SDNode" ? "N" : "inN"; OS << "static inline bool Predicate_" << Fragments[i]->getName() From lattner at cs.uiuc.edu Thu Sep 8 16:27:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 16:27:26 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509082127.QAA25725@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.4 -> 1.5 DAGISelEmitter.h updated: 1.3 -> 1.4 --- Log message: Parse information about type constraints on SDNodes --- Diffs of the changes: (+71 -0) DAGISelEmitter.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ DAGISelEmitter.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.4 llvm/utils/TableGen/DAGISelEmitter.cpp:1.5 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.4 Thu Sep 8 16:04:46 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 16:27:15 2005 @@ -19,11 +19,51 @@ using namespace llvm; //===----------------------------------------------------------------------===// +// SDTypeConstraint implementation +// + +SDTypeConstraint::SDTypeConstraint(Record *R) { + OperandNo = R->getValueAsInt("OperandNum"); + + if (R->isSubClassOf("SDTCisVT")) { + ConstraintType = SDTCisVT; + x.SDTCisVT_Info.VT = getValueType(R->getValueAsDef("VT")); + } else if (R->isSubClassOf("SDTCisInt")) { + ConstraintType = SDTCisInt; + } else if (R->isSubClassOf("SDTCisFP")) { + ConstraintType = SDTCisFP; + } else if (R->isSubClassOf("SDTCisSameAs")) { + ConstraintType = SDTCisSameAs; + x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); + } else if (R->isSubClassOf("SDTCisVTSmallerThanOp")) { + ConstraintType = SDTCisVTSmallerThanOp; + x.SDTCisVTSmallerThanOp_Info.OtherOperandNum = + R->getValueAsInt("OtherOperandNum"); + } else { + std::cerr << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n"; + exit(1); + } +} + +//===----------------------------------------------------------------------===// // SDNodeInfo implementation // SDNodeInfo::SDNodeInfo(Record *R) : Def(R) { EnumName = R->getValueAsString("Opcode"); SDClassName = R->getValueAsString("SDClass"); + Record *TypeProfile = R->getValueAsDef("TypeProfile"); + NumResults = TypeProfile->getValueAsInt("NumResults"); + NumOperands = TypeProfile->getValueAsInt("NumOperands"); + + // Parse the type constraints. + ListInit *Constraints = TypeProfile->getValueAsListInit("Constraints"); + for (unsigned i = 0, e = Constraints->getSize(); i != e; ++i) { + assert(dynamic_cast(Constraints->getElement(i)) && + "Constraints list should contain constraint definitions!"); + Record *Constraint = + static_cast(Constraints->getElement(i))->getDef(); + TypeConstraints.push_back(Constraint); + } } //===----------------------------------------------------------------------===// Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.3 llvm/utils/TableGen/DAGISelEmitter.h:1.4 --- llvm/utils/TableGen/DAGISelEmitter.h:1.3 Thu Sep 8 16:03:01 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Sep 8 16:27:15 2005 @@ -24,6 +24,29 @@ class TreePattern; class DAGISelEmitter; + /// SDTypeConstraint - This is a discriminated union of constraints, + /// corresponding to the SDTypeConstraint tablegen class in Target.td. + struct SDTypeConstraint { + SDTypeConstraint(Record *R); + + unsigned OperandNo; // The operand # this constraint applies to. + enum { + SDTCisVT, SDTCisInt, SDTCisFP, SDTCisSameAs, SDTCisVTSmallerThanOp + } ConstraintType; + + union { // The discriminated union. + struct { + MVT::ValueType VT; + } SDTCisVT_Info; + struct { + unsigned OtherOperandNum; + } SDTCisSameAs_Info; + struct { + unsigned OtherOperandNum; + } SDTCisVTSmallerThanOp_Info; + } x; + }; + /// SDNodeInfo - One of these records is created for each SDNode instance in /// the target .td file. This represents the various dag nodes we will be /// processing. @@ -31,12 +54,20 @@ Record *Def; std::string EnumName; std::string SDClassName; + int NumResults, NumOperands; + std::vector TypeConstraints; public: SDNodeInfo(Record *R); // Parse the specified record. + int getNumResults() const { return NumResults; } + int getNumOperands() const { return NumOperands; } Record *getRecord() const { return Def; } const std::string &getEnumName() const { return EnumName; } const std::string &getSDClassName() const { return SDClassName; } + + const std::vector &getTypeConstraints() { + return TypeConstraints; + } }; /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped From lattner at cs.uiuc.edu Thu Sep 8 16:43:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 16:43:32 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenRegisters.h CodeGenTarget.cpp CodeGenTarget.h Message-ID: <200509082143.QAA28827@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenRegisters.h updated: 1.7 -> 1.8 CodeGenTarget.cpp updated: 1.35 -> 1.36 CodeGenTarget.h updated: 1.17 -> 1.18 --- Log message: Compute the value types that are natively supported by a target. --- Diffs of the changes: (+25 -2) CodeGenRegisters.h | 2 ++ CodeGenTarget.cpp | 6 ++++++ CodeGenTarget.h | 19 +++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) Index: llvm/utils/TableGen/CodeGenRegisters.h diff -u llvm/utils/TableGen/CodeGenRegisters.h:1.7 llvm/utils/TableGen/CodeGenRegisters.h:1.8 --- llvm/utils/TableGen/CodeGenRegisters.h:1.7 Fri Aug 19 14:12:51 2005 +++ llvm/utils/TableGen/CodeGenRegisters.h Thu Sep 8 16:43:21 2005 @@ -17,6 +17,7 @@ #include #include +#include "llvm/CodeGen/ValueTypes.h" namespace llvm { class Record; @@ -36,6 +37,7 @@ std::vector Elements; unsigned SpillSize; unsigned SpillAlignment; + MVT::ValueType VT; std::string MethodProtos, MethodBodies; const std::string &getName() const; Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.35 llvm/utils/TableGen/CodeGenTarget.cpp:1.36 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.35 Fri Aug 26 15:55:40 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Thu Sep 8 16:43:21 2005 @@ -152,6 +152,7 @@ Namespace = R->getValueAsString("Namespace"); SpillSize = R->getValueAsInt("Size"); SpillAlignment = R->getValueAsInt("Alignment"); + VT = getValueType(R->getValueAsDef("RegType")); if (CodeInit *CI = dynamic_cast(R->getValueInit("MethodBodies"))) MethodBodies = CI->getValue(); @@ -182,6 +183,11 @@ return TheDef->getName(); } +void CodeGenTarget::ReadLegalValueTypes() const { + const std::vector &RCs = getRegisterClasses(); + for (unsigned i = 0, e = RCs.size(); i != e; ++i) + LegalValueTypes.push_back(RCs[i].VT); +} void CodeGenTarget::ReadInstructions() const { Index: llvm/utils/TableGen/CodeGenTarget.h diff -u llvm/utils/TableGen/CodeGenTarget.h:1.17 llvm/utils/TableGen/CodeGenTarget.h:1.18 --- llvm/utils/TableGen/CodeGenTarget.h:1.17 Thu Apr 21 19:00:35 2005 +++ llvm/utils/TableGen/CodeGenTarget.h Thu Sep 8 16:43:21 2005 @@ -47,9 +47,11 @@ mutable std::map Instructions; mutable std::vector Registers; mutable std::vector RegisterClasses; + mutable std::vector LegalValueTypes; void ReadRegisters() const; void ReadRegisterClasses() const; void ReadInstructions() const; + void ReadLegalValueTypes() const; public: CodeGenTarget(); @@ -70,16 +72,29 @@ /// Record *getAsmWriter() const; - const std::vector &getRegisters() { + const std::vector &getRegisters() const { if (Registers.empty()) ReadRegisters(); return Registers; } - const std::vector getRegisterClasses() { + const std::vector &getRegisterClasses() const { if (RegisterClasses.empty()) ReadRegisterClasses(); return RegisterClasses; } + const std::vector &getLegalValueTypes() const { + if (LegalValueTypes.empty()) ReadLegalValueTypes(); + return LegalValueTypes; + } + + /// isLegalValueType - Return true if the specified value type is natively + /// supported by the target (i.e. there are registers that directly hold it). + bool isLegalValueType(MVT::ValueType VT) const { + const std::vector &LegalVTs = getLegalValueTypes(); + for (unsigned i = 0, e = LegalVTs.size(); i != e; ++i) + if (LegalVTs[i] == VT) return true; + return false; + } /// getInstructions - Return all of the instructions defined for this target. /// From lattner at cs.uiuc.edu Thu Sep 8 18:17:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 18:17:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509082317.SAA11944@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.94 -> 1.95 --- Log message: whitespace/comment changes, no functionality diffs --- Diffs of the changes: (+5 -2) PowerPCInstrInfo.td | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.94 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.95 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.94 Thu Sep 8 14:50:41 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 8 18:17:26 2005 @@ -17,7 +17,8 @@ //===----------------------------------------------------------------------===// // Selection DAG Type Constraint definitions. // -// Note that the semantics of these constraints are hard coded into tblgen. +// Note that the semantics of these constraints are hard coded into tblgen. To +// modify or add constraints, you have to hack tblgen. // class SDTypeConstraint { @@ -66,7 +67,9 @@ // Builtin profiles. def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt' -def SDTBinOp : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>]>; +def SDTBinOp : SDTypeProfile<1, 2, [ // add, mul, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> +]>; def SDTIntBinOp : SDTypeProfile<1, 2, [ // and, or, xor, udiv, etc. SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> ]>; From lattner at cs.uiuc.edu Thu Sep 8 18:22:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 18:22:59 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509082322.SAA12166@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.5 -> 1.6 DAGISelEmitter.h updated: 1.4 -> 1.5 --- Log message: Implement a complete type inference system for dag patterns, based on the constraints defined in the DAG node definitions in the .td files. This allows us to infer (and check!) the types for all nodes in the current ppc .td file. For example, instead of: Inst pattern EQV: (set GPRC:i32:$rT, (xor (xor GPRC:i32:$rA, GPRC:i32:$rB), (imm)<>)) we now fully infer: Inst pattern EQV: (set:void GPRC:i32:$rT, (xor:i32 (xor:i32 GPRC:i32:$rA, GPRC:i32:$rB), (imm:i32)<>)) from: (set GPRC:$rT, (not (xor GPRC:$rA, GPRC:$rB))) --- Diffs of the changes: (+234 -13) DAGISelEmitter.cpp | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++--- DAGISelEmitter.h | 62 ++++++++++++++++- 2 files changed, 234 insertions(+), 13 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.5 llvm/utils/TableGen/DAGISelEmitter.cpp:1.6 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.5 Thu Sep 8 16:27:15 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 18:22:48 2005 @@ -45,6 +45,87 @@ } } +/// getOperandNum - Return the node corresponding to operand #OpNo in tree +/// N, which has NumResults results. +TreePatternNode *SDTypeConstraint::getOperandNum(unsigned OpNo, + TreePatternNode *N, + unsigned NumResults) const { + assert(NumResults == 1 && "We only work with single result nodes so far!"); + + if (OpNo < NumResults) + return N; // FIXME: need value # + else + return N->getChild(OpNo-NumResults); +} + +/// ApplyTypeConstraint - Given a node in a pattern, apply this type +/// constraint to the nodes operands. This returns true if it makes a +/// change, false otherwise. If a type contradiction is found, throw an +/// exception. +bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, + const SDNodeInfo &NodeInfo, + TreePattern &TP) const { + unsigned NumResults = NodeInfo.getNumResults(); + assert(NumResults == 1 && "We only work with single result nodes so far!"); + + // Check that the number of operands is sane. + if (NodeInfo.getNumOperands() >= 0) { + if (N->getNumChildren() != (unsigned)NodeInfo.getNumOperands()) + TP.error(N->getOperator()->getName() + " node requires exactly " + + itostr(NodeInfo.getNumOperands()) + " operands!"); + } + + TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NumResults); + + switch (ConstraintType) { + default: assert(0 && "Unknown constraint type!"); + case SDTCisVT: + // Operand must be a particular type. + return NodeToApply->UpdateNodeType(x.SDTCisVT_Info.VT, TP); + case SDTCisInt: + if (NodeToApply->hasTypeSet() && !MVT::isInteger(NodeToApply->getType())) + NodeToApply->UpdateNodeType(MVT::i1, TP); // throw an error. + + // FIXME: can tell from the target if there is only one Int type supported. + return false; + case SDTCisFP: + if (NodeToApply->hasTypeSet() && + !MVT::isFloatingPoint(NodeToApply->getType())) + NodeToApply->UpdateNodeType(MVT::f32, TP); // throw an error. + // FIXME: can tell from the target if there is only one FP type supported. + return false; + case SDTCisSameAs: { + TreePatternNode *OtherNode = + getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NumResults); + return NodeToApply->UpdateNodeType(OtherNode->getType(), TP) | + OtherNode->UpdateNodeType(NodeToApply->getType(), TP); + } + case SDTCisVTSmallerThanOp: { + // The NodeToApply must be a leaf node that is a VT. OtherOperandNum must + // have an integer type that is smaller than the VT. + if (!NodeToApply->isLeaf() || + !dynamic_cast(NodeToApply->getLeafValue()) || + !static_cast(NodeToApply->getLeafValue())->getDef() + ->isSubClassOf("ValueType")) + TP.error(N->getOperator()->getName() + " expects a VT operand!"); + MVT::ValueType VT = + getValueType(static_cast(NodeToApply->getLeafValue())->getDef()); + if (!MVT::isInteger(VT)) + TP.error(N->getOperator()->getName() + " VT operand must be integer!"); + + TreePatternNode *OtherNode = + getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N,NumResults); + if (OtherNode->hasTypeSet() && + (!MVT::isInteger(OtherNode->getType()) || + OtherNode->getType() <= VT)) + OtherNode->UpdateNodeType(MVT::Other, TP); // Throw an error. + return false; + } + } + return false; +} + + //===----------------------------------------------------------------------===// // SDNodeInfo implementation // @@ -77,6 +158,23 @@ #endif } +/// UpdateNodeType - Set the node type of N to VT if VT contains +/// information. If N already contains a conflicting type, then throw an +/// exception. This returns true if any information was updated. +/// +bool TreePatternNode::UpdateNodeType(MVT::ValueType VT, TreePattern &TP) { + if (VT == MVT::LAST_VALUETYPE || getType() == VT) return false; + if (getType() == MVT::LAST_VALUETYPE) { + setType(VT); + return true; + } + + TP.error("Type inference contradiction found in node " + + getOperator()->getName() + "!"); + return true; // unreachable +} + + void TreePatternNode::print(std::ostream &OS) const { if (isLeaf()) { OS << *getLeafValue(); @@ -132,6 +230,8 @@ return New; } +/// SubstituteFormalArguments - Replace the formal arguments in this tree +/// with actual values specified by ArgMap. void TreePatternNode:: SubstituteFormalArguments(std::map &ArgMap) { if (isLeaf()) return; @@ -196,6 +296,35 @@ return FragTree; } +/// ApplyTypeConstraints - Apply all of the type constraints relevent to +/// this node and its children in the tree. This returns true if it makes a +/// change, false otherwise. If a type contradiction is found, throw an +/// exception. +bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP) { + if (isLeaf()) return false; + + // special handling for set, which isn't really an SDNode. + if (getOperator()->getName() == "set") { + assert (getNumChildren() == 2 && "Only handle 2 operand set's for now!"); + bool MadeChange = getChild(0)->ApplyTypeConstraints(TP); + MadeChange |= getChild(1)->ApplyTypeConstraints(TP); + + // Types of operands must match. + MadeChange |= getChild(0)->UpdateNodeType(getChild(1)->getType(), TP); + MadeChange |= getChild(1)->UpdateNodeType(getChild(0)->getType(), TP); + MadeChange |= UpdateNodeType(MVT::isVoid, TP); + return MadeChange; + } + + const SDNodeInfo &NI = TP.getDAGISelEmitter().getSDNodeInfo(getOperator()); + + bool MadeChange = NI.ApplyTypeConstraints(this, TP); + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + MadeChange |= getChild(i)->ApplyTypeConstraints(TP); + return MadeChange; +} + + //===----------------------------------------------------------------------===// // TreePattern implementation // @@ -311,9 +440,8 @@ return 0; } - // Apply the type cast... - assert(0 && "unimp yet"); - //New->updateNodeType(getValueType(Operator), TheRecord->getName()); + // Apply the type cast. + New->UpdateNodeType(getValueType(Operator), *this); return New; } @@ -361,6 +489,23 @@ return new TreePatternNode(Operator, Children); } +/// InferAllTypes - Infer/propagate as many types throughout the expression +/// patterns as possible. Return true if all types are infered, false +/// otherwise. Throw an exception if a type contradiction is found. +bool TreePattern::InferAllTypes() { + bool MadeChange = true; + while (MadeChange) { + MadeChange = false; + for (unsigned i = 0, e = Trees.size(); i != e; ++i) + MadeChange |= Trees[i]->ApplyTypeConstraints(*this); + } + + bool HasUnresolvedTypes = false; + for (unsigned i = 0, e = Trees.size(); i != e; ++i) + HasUnresolvedTypes |= Trees[i]->ContainsUnresolvedType(); + return !HasUnresolvedTypes; +} + void TreePattern::print(std::ostream &OS) const { switch (getPatternType()) { case TreePattern::PatFrag: OS << "PatFrag pattern "; break; @@ -449,9 +594,22 @@ // that there are not references to PatFrags left inside of them. for (std::map::iterator I = PatternFragments.begin(), E = PatternFragments.end(); I != E; ++I) { - I->second->InlinePatternFragments(); + TreePattern *ThePat = I->second; + ThePat->InlinePatternFragments(); + + // Infer as many types as possible. Don't worry about it if we don't infer + // all of them, some may depend on the inputs of the pattern. + try { + ThePat->InferAllTypes(); + } catch (...) { + // If this pattern fragment is not supported by this target (no types can + // satisfy its constraints), just ignore it. If the bogus pattern is + // actually used by instructions, the type consistency error will be + // reported there. + } + // If debugging, print out the pattern fragment result. - DEBUG(I->second->dump()); + DEBUG(ThePat->dump()); } } @@ -473,12 +631,21 @@ Trees.push_back((DagInit*)LI->getElement(j)); // Parse the instruction. - Instructions.push_back(new TreePattern(TreePattern::Instruction, Instrs[i], - Trees, *this)); + TreePattern *I = new TreePattern(TreePattern::Instruction, Instrs[i], + Trees, *this); // Inline pattern fragments into it. - Instructions.back()->InlinePatternFragments(); + I->InlinePatternFragments(); + + // Infer as many types as possible. Don't worry about it if we don't infer + // all of them, some may depend on the inputs of the pattern. + if (!I->InferAllTypes()) { + I->dump(); + I->error("Could not infer all types in pattern!"); + } + + DEBUG(I->dump()); - DEBUG(Instructions.back()->dump()); + Instructions.push_back(I); } } Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.4 llvm/utils/TableGen/DAGISelEmitter.h:1.5 --- llvm/utils/TableGen/DAGISelEmitter.h:1.4 Thu Sep 8 16:27:15 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Sep 8 18:22:48 2005 @@ -21,7 +21,9 @@ class Record; class Init; class DagInit; + class SDNodeInfo; class TreePattern; + class TreePatternNode; class DAGISelEmitter; /// SDTypeConstraint - This is a discriminated union of constraints, @@ -45,6 +47,18 @@ unsigned OtherOperandNum; } SDTCisVTSmallerThanOp_Info; } x; + + /// ApplyTypeConstraint - Given a node in a pattern, apply this type + /// constraint to the nodes operands. This returns true if it makes a + /// change, false otherwise. If a type contradiction is found, throw an + /// exception. + bool ApplyTypeConstraint(TreePatternNode *N, const SDNodeInfo &NodeInfo, + TreePattern &TP) const; + + /// getOperandNum - Return the node corresponding to operand #OpNo in tree + /// N, which has NumResults results. + TreePatternNode *getOperandNum(unsigned OpNo, TreePatternNode *N, + unsigned NumResults) const; }; /// SDNodeInfo - One of these records is created for each SDNode instance in @@ -54,20 +68,32 @@ Record *Def; std::string EnumName; std::string SDClassName; - int NumResults, NumOperands; + unsigned NumResults; + int NumOperands; std::vector TypeConstraints; public: SDNodeInfo(Record *R); // Parse the specified record. - int getNumResults() const { return NumResults; } + unsigned getNumResults() const { return NumResults; } int getNumOperands() const { return NumOperands; } Record *getRecord() const { return Def; } const std::string &getEnumName() const { return EnumName; } const std::string &getSDClassName() const { return SDClassName; } - const std::vector &getTypeConstraints() { + const std::vector &getTypeConstraints() const { return TypeConstraints; } + + /// ApplyTypeConstraints - Given a node in a pattern, apply the type + /// constraints for this node to the operands of the node. This returns + /// true if it makes a change, false otherwise. If a type contradiction is + /// found, throw an exception. + bool ApplyTypeConstraints(TreePatternNode *N, TreePattern &TP) const { + bool MadeChange = false; + for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) + MadeChange |= TypeConstraints[i].ApplyTypeConstraint(N, *this, TP); + return MadeChange; + } }; /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped @@ -106,6 +132,7 @@ void setName(const std::string &N) { Name = N; } bool isLeaf() const { return Val != 0; } + bool hasTypeSet() const { return Ty != MVT::LAST_VALUETYPE; } MVT::ValueType getType() const { return Ty; } void setType(MVT::ValueType VT) { Ty = VT; } @@ -130,6 +157,8 @@ /// TreePatternNode *clone() const; + /// SubstituteFormalArguments - Replace the formal arguments in this tree + /// with actual values specified by ArgMap. void SubstituteFormalArguments(std::map &ArgMap); @@ -137,7 +166,27 @@ /// fragments, inline them into place, giving us a pattern without any /// PatFrag references. TreePatternNode *InlinePatternFragments(TreePattern &TP); - + + /// ApplyTypeConstraints - Apply all of the type constraints relevent to + /// this node and its children in the tree. This returns true if it makes a + /// change, false otherwise. If a type contradiction is found, throw an + /// exception. + bool ApplyTypeConstraints(TreePattern &TP); + + /// UpdateNodeType - Set the node type of N to VT if VT contains + /// information. If N already contains a conflicting type, then throw an + /// exception. This returns true if any information was updated. + /// + bool UpdateNodeType(MVT::ValueType VT, TreePattern &TP); + + /// ContainsUnresolvedType - Return true if this tree contains any + /// unresolved types. + bool ContainsUnresolvedType() const { + if (Ty == MVT::LAST_VALUETYPE) return true; + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + if (getChild(i)->ContainsUnresolvedType()) return true; + return false; + } }; @@ -206,6 +255,11 @@ Trees[i] = Trees[i]->InlinePatternFragments(*this); } + /// InferAllTypes - Infer/propagate as many types throughout the expression + /// patterns as possible. Return true if all types are infered, false + /// otherwise. Throw an exception if a type contradiction is found. + bool InferAllTypes(); + /// error - Throw an exception, prefixing it with information about this /// pattern. void error(const std::string &Msg) const; From lattner at cs.uiuc.edu Thu Sep 8 18:26:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 18:26:41 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509082326.SAA12245@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.6 -> 1.7 --- Log message: Fix incorrect comment --- Diffs of the changes: (+2 -3) DAGISelEmitter.cpp | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.6 llvm/utils/TableGen/DAGISelEmitter.cpp:1.7 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.6 Thu Sep 8 18:22:48 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 18:26:30 2005 @@ -636,15 +636,14 @@ // Inline pattern fragments into it. I->InlinePatternFragments(); - // Infer as many types as possible. Don't worry about it if we don't infer - // all of them, some may depend on the inputs of the pattern. + // Infer as many types as possible. If we cannot infer all of them, we can + // never do anything with this instruction pattern: report it to the user. if (!I->InferAllTypes()) { I->dump(); I->error("Could not infer all types in pattern!"); } DEBUG(I->dump()); - Instructions.push_back(I); } } From lattner at cs.uiuc.edu Thu Sep 8 19:40:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 19:40:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509090040.TAA13692@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.95 -> 1.96 --- Log message: Introduce two new concepts: 1. Add support for defining Pattern's, which can match expressions when there is no instruction that directly implements something. Instructions usually implicitly define patterns. 2. Add support for defining SDNodeXForm's, which are node transformations. This seperates the concept of a node xform out from the existing predicate support. Using this new stuff, we add a few instruction patterns, one for testing, and two for OR/XOR by an arbitrary immediate. --- Diffs of the changes: (+75 -11) PowerPCInstrInfo.td | 86 +++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 75 insertions(+), 11 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.95 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.96 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.95 Thu Sep 8 18:17:26 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Thu Sep 8 19:39:56 2005 @@ -109,24 +109,44 @@ def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; +//===----------------------------------------------------------------------===// +// Selection DAG Node Transformation Functions. +// +// This mechanism allows targets to manipulate nodes in the output DAG once a +// match has been formed. This is typically used to manipulate immediate +// values. +// +class SDNodeXForm { + SDNode Opcode = opc; + code XFormFunction = xformFunction; +} + +def NOOP_SDNodeXForm : SDNodeXForm; + //===----------------------------------------------------------------------===// // Selection DAG Pattern Fragments. // +// Pattern fragments are reusable chunks of dags that match specific things. +// They can take arguments and have C++ predicates that control whether they +// match. They are intended to make the patterns for common instructions more +// compact and readable. +// /// PatFrag - Represents a pattern fragment. This can match something on the /// DAG, frame a single node to multiply nested other fragments. /// -class PatFrag { +class PatFrag { dag Operands = ops; dag Fragment = frag; code Predicate = pred; - code OperandTransform = xform; + SDNodeXForm OperandTransform = xform; } // PatLeaf's are pattern fragments that have no operands. This is just a helper // to define immediates and other common things concisely. -class PatLeaf +class PatLeaf : PatFrag<(ops), frag, pred, xform>; // Leaf fragments. @@ -142,10 +162,39 @@ def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; +//===----------------------------------------------------------------------===// +// Selection DAG Pattern Support. +// +// Patterns are what are actually matched against the target-flavored +// instruction selection DAG. Instructions defined by the target implicitly +// define patterns in most cases, but patterns can also be explicitly added when +// an operation is defined by a sequence of instructions (e.g. loading a large +// immediate value on RISC targets that do not support immediates as large as +// their GPRs). +// + +class Pattern resultInstrs> { + dag PatternToMatch = patternToMatch; + list ResultInstrs = resultInstrs; +} + +// Pat - A simple (but common) form of a pattern, which produces a simple result +// not needing a full list. +class Pat : Pattern; //===----------------------------------------------------------------------===// -// PowerPC specific pattern fragments. +// PowerPC specific transformation functions and pattern fragments. +// +def LO16 : SDNodeXFormgetValue()); +}]>; + +def HI16 : SDNodeXFormgetValue() >> 16); +}]>; def immSExt16 : PatLeaf<(imm), [{ // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended @@ -156,15 +205,13 @@ // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended // field. Used by instructions like 'ori'. return (unsigned)N->getValue() == (unsigned short)N->getValue(); -}]>; +}], LO16>; + def imm16Shifted : PatLeaf<(imm), [{ // imm16Shifted predicate - True if only bits in the top 16-bits of the // immediate are set. Used by instructions like 'addis'. return ((unsigned)N->getValue() & 0xFFFF0000U) == (unsigned)N->getValue(); -}], [{ - // Transformation function: shift the immediate value down into the low bits. - return getI32Imm((unsigned)N->getValue() >> 16); -}]>; +}], HI16>; /* // Example of a legalize expander: Only for PPC64. @@ -176,8 +223,6 @@ Subtarget_PPC64>; */ - - //===----------------------------------------------------------------------===// // PowerPC Flag Definitions. @@ -712,6 +757,24 @@ (ops GPRC:$rA, GPRC:$rS, u6imm:$SH, u6imm:$ME), "rldicr $rA, $rS, $SH, $ME">, isPPC64; +//===----------------------------------------------------------------------===// +// PowerPC Instruction Patterns +// + +// REDUNDANT WITH INSTRUCTION DEFINITION, ONLY FOR TESTING. +def : Pat<(sext_inreg GPRC:$in, i8), + (EXTSB GPRC:$in)>; + +// or by an arbitrary immediate. +def : Pat<(or GPRC:$in, imm:$imm), + (ORIS (ORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; +// xor by an arbitrary immediate. +def : Pat<(xor GPRC:$in, imm:$imm), + (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; + +//===----------------------------------------------------------------------===// +// PowerPCInstrInfo Definition +// def PowerPCInstrInfo : InstrInfo { let PHIInst = PHI; @@ -720,3 +783,4 @@ let isLittleEndianEncoding = 1; } + From lattner at cs.uiuc.edu Thu Sep 8 20:11:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 20:11:29 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.h Message-ID: <200509090111.UAA18168@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.h updated: 1.5 -> 1.6 --- Log message: add some accessors --- Diffs of the changes: (+2 -0) DAGISelEmitter.h | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.5 llvm/utils/TableGen/DAGISelEmitter.h:1.6 --- llvm/utils/TableGen/DAGISelEmitter.h:1.5 Thu Sep 8 18:22:48 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Sep 8 20:11:17 2005 @@ -233,6 +233,8 @@ /// getTrees - Return the tree patterns which corresponds to this pattern. /// const std::vector &getTrees() const { return Trees; } + unsigned getNumTrees() const { return Trees.size(); } + TreePatternNode *getTree(unsigned i) const { return Trees[i]; } /// getRecord - Return the actual TableGen record corresponding to this /// pattern. From lattner at cs.uiuc.edu Thu Sep 8 20:11:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 20:11:56 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200509090111.UAA18207@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.7 -> 1.8 --- Log message: use new accessors to simplify code. Add checking to make sure top-level instr definitions are void --- Diffs of the changes: (+12 -4) DAGISelEmitter.cpp | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.7 llvm/utils/TableGen/DAGISelEmitter.cpp:1.8 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.7 Thu Sep 8 18:26:30 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 20:11:44 2005 @@ -277,7 +277,7 @@ TP.error("'" + Op->getName() + "' fragment requires " + utostr(Frag->getNumArgs()) + " operands!"); - TreePatternNode *FragTree = Frag->getTrees()[0]->clone(); + TreePatternNode *FragTree = Frag->getTree(0)->clone(); // Resolve formal arguments to their actual value. if (Frag->getNumArgs()) { @@ -574,9 +574,9 @@ CodeInit *CI = dynamic_cast(Fragments[i]->getValueInit("Predicate")); if (!CI->getValue().empty()) { - assert(!P->getTrees()[0]->isLeaf() && "Can't be a leaf!"); + assert(!P->getTree(0)->isLeaf() && "Can't be a leaf!"); std::string ClassName = - getSDNodeInfo(P->getTrees()[0]->getOperator()).getSDClassName(); + getSDNodeInfo(P->getTree(0)->getOperator()).getSDClassName(); const char *C2 = ClassName == "SDNode" ? "N" : "inN"; OS << "static inline bool Predicate_" << Fragments[i]->getName() @@ -584,7 +584,7 @@ if (ClassName != "SDNode") OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n"; OS << CI->getValue() << "\n}\n"; - P->getTrees()[0]->setPredicateFn("Predicate_"+Fragments[i]->getName()); + P->getTree(0)->setPredicateFn("Predicate_"+Fragments[i]->getName()); } } @@ -642,6 +642,14 @@ I->dump(); I->error("Could not infer all types in pattern!"); } + + // Verify that the top-level forms in the instruction are of void type. + for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) + if (I->getTree(j)->getType() != MVT::isVoid) { + I->dump(); + I->error("Top-level forms in instruction pattern should have" + " void types"); + } DEBUG(I->dump()); Instructions.push_back(I); From lattner at cs.uiuc.edu Thu Sep 8 20:15:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 8 Sep 2005 20:15:13 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h Message-ID: <200509090115.UAA18367@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.8 -> 1.9 DAGISelEmitter.h updated: 1.6 -> 1.7 --- Log message: add an accessor to provide more checking --- Diffs of the changes: (+9 -5) DAGISelEmitter.cpp | 10 +++++----- DAGISelEmitter.h | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.8 llvm/utils/TableGen/DAGISelEmitter.cpp:1.9 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.8 Thu Sep 8 20:11:44 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Sep 8 20:15:01 2005 @@ -277,7 +277,7 @@ TP.error("'" + Op->getName() + "' fragment requires " + utostr(Frag->getNumArgs()) + " operands!"); - TreePatternNode *FragTree = Frag->getTree(0)->clone(); + TreePatternNode *FragTree = Frag->getOnlyTree()->clone(); // Resolve formal arguments to their actual value. if (Frag->getNumArgs()) { @@ -400,7 +400,7 @@ if (R->isSubClassOf("RegisterClass")) return getValueType(R->getValueAsDef("RegType")); else if (R->isSubClassOf("PatFrag")) { - //return ISE.ReadNonterminal(R)->getTree()->getType(); + // Pattern fragment types will be resolved when they are inlined. return MVT::LAST_VALUETYPE; } else if (R->isSubClassOf("Register")) { assert(0 && "Explicit registers not handled here yet!\n"); @@ -574,9 +574,9 @@ CodeInit *CI = dynamic_cast(Fragments[i]->getValueInit("Predicate")); if (!CI->getValue().empty()) { - assert(!P->getTree(0)->isLeaf() && "Can't be a leaf!"); + assert(!P->getOnlyTree()->isLeaf() && "Can't be a leaf!"); std::string ClassName = - getSDNodeInfo(P->getTree(0)->getOperator()).getSDClassName(); + getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName(); const char *C2 = ClassName == "SDNode" ? "N" : "inN"; OS << "static inline bool Predicate_" << Fragments[i]->getName() @@ -584,7 +584,7 @@ if (ClassName != "SDNode") OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n"; OS << CI->getValue() << "\n}\n"; - P->getTree(0)->setPredicateFn("Predicate_"+Fragments[i]->getName()); + P->getOnlyTree()->setPredicateFn("Predicate_"+Fragments[i]->getName()); } } Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.6 llvm/utils/TableGen/DAGISelEmitter.h:1.7 --- llvm/utils/TableGen/DAGISelEmitter.h:1.6 Thu Sep 8 20:11:17 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Thu Sep 8 20:15:01 2005 @@ -235,6 +235,10 @@ const std::vector &getTrees() const { return Trees; } unsigned getNumTrees() const { return Trees.size(); } TreePatternNode *getTree(unsigned i) const { return Trees[i]; } + TreePatternNode *getOnlyTree() const { + assert(Trees.size() == 1 && "Doesn't have exactly one pattern!"); + return Trees[0]; + } /// getRecord - Return the actual TableGen record corresponding to this /// pattern. From lattner at cs.uiuc.edu Fri Sep 9 12:49:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 12:49:09 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/rlwimi-commute.ll Message-ID: <200509091749.MAA29928@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: rlwimi-commute.ll added (r1.1) --- Log message: New testcase, neither should require a register-register copy --- Diffs of the changes: (+26 -0) rlwimi-commute.ll | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/rlwimi-commute.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/rlwimi-commute.ll:1.1 *** /dev/null Fri Sep 9 12:49:07 2005 --- llvm/test/Regression/CodeGen/PowerPC/rlwimi-commute.ll Fri Sep 9 12:48:57 2005 *************** *** 0 **** --- 1,26 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | grep rlwimi && + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep 'or ' + + ; Make sure there is no register-register copies here. + + void %test1(int *%A, int *%B, int *%D, int* %E) { + %A = load int* %A + %B = load int* %B + %X = and int %A, 15 + %Y = and int %B, -16 + %Z = or int %X, %Y + store int %Z, int* %D + store int %A, int* %E + ret void + } + + void %test2(int *%A, int *%B, int *%D, int* %E) { + %A = load int* %A + %B = load int* %B + %X = and int %A, 15 + %Y = and int %B, -16 + %Z = or int %X, %Y + store int %Z, int* %D + store int %B, int* %E + ret void + } From jlaskey at apple.com Fri Sep 9 12:50:32 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 9 Sep 2005 12:50:32 -0500 Subject: [llvm-commits] CVS: llvm/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200509091750.MAA29985@zion.cs.uiuc.edu> Changes in directory llvm/Xcode/LLVM.xcodeproj: project.pbxproj updated: 1.9 -> 1.10 --- Log message: Added targets to speed up build of llc. --- Diffs of the changes: (+309 -2) project.pbxproj | 311 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 309 insertions(+), 2 deletions(-) Index: llvm/Xcode/LLVM.xcodeproj/project.pbxproj diff -u llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.9 llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.10 --- llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.9 Wed Sep 7 18:57:00 2005 +++ llvm/Xcode/LLVM.xcodeproj/project.pbxproj Fri Sep 9 12:50:20 2005 @@ -6,6 +6,34 @@ objectVersion = 42; objects = { +/* Begin PBXAggregateTarget section */ + CF0329BC08D1BE8E0030FD33 /* LLVM full llc */ = { + isa = PBXAggregateTarget; + buildConfigurationList = CF0329C708D1BEC40030FD33 /* Build configuration list for PBXAggregateTarget "LLVM full llc" */; + buildPhases = ( + ); + buildSettings = { + OPTIMIZATION_CFLAGS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM full llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + dependencies = ( + CF0329BE08D1BE970030FD33 /* PBXTargetDependency */, + CF0329C008D1BE9B0030FD33 /* PBXTargetDependency */, + ); + name = "LLVM full llc"; + productName = "LLVM full llc"; + }; +/* End PBXAggregateTarget section */ + /* Begin PBXBuildStyle section */ 014CEA520018CE5811CA2923 /* Debug */ = { isa = PBXBuildStyle; @@ -32,6 +60,23 @@ }; /* End PBXBuildStyle section */ +/* Begin PBXContainerItemProxy section */ + CF0329BD08D1BE970030FD33 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CF0329B608D1BE110030FD33; + remoteInfo = "LLVM lib"; + }; + CF0329BF08D1BE9B0030FD33 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CF0329BB08D1BE5D0030FD33; + remoteInfo = "LLVM llc"; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ CF9BCD0808C74DE0001E7011 /* SubtargetFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtargetFeature.h; sourceTree = ""; }; CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtargetFeature.cpp; sourceTree = ""; }; @@ -2287,9 +2332,63 @@ /* End PBXGroup section */ /* Begin PBXLegacyTarget section */ + CF0329B608D1BE110030FD33 /* LLVM lib */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION) -j 4 "; + buildConfigurationList = CF0329B708D1BE530030FD33 /* Build configuration list for PBXLegacyTarget "LLVM lib" */; + buildPhases = ( + ); + buildSettings = { + OPTIMIZATION_CFLAGS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM lib"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + buildToolPath = /usr/bin/make; + buildWorkingDirectory = ../../obj/lib; + dependencies = ( + ); + name = "LLVM lib"; + passBuildSettingsInEnvironment = 0; + productName = "LLVM lib"; + }; + CF0329BB08D1BE5D0030FD33 /* LLVM llc */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION) -j 4 "; + buildConfigurationList = CF0329C308D1BEC40030FD33 /* Build configuration list for PBXLegacyTarget "LLVM llc" */; + buildPhases = ( + ); + buildSettings = { + OPTIMIZATION_CFLAGS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + buildToolPath = /usr/bin/make; + buildWorkingDirectory = ../../obj/tools/llc; + dependencies = ( + ); + name = "LLVM llc"; + passBuildSettingsInEnvironment = 0; + productName = "LLVM llc"; + }; D28A88AD04BDD90700651E21 /* LLVM */ = { isa = PBXLegacyTarget; - buildArgumentsString = "$(ACTION) -j 4"; + buildArgumentsString = "$(ACTION) -j 4 "; buildConfigurationList = DE66EC4C08ABE78900323D32 /* Build configuration list for PBXLegacyTarget "LLVM" */; buildPhases = ( ); @@ -2299,7 +2398,7 @@ PRODUCT_NAME = LLVM; }; buildToolPath = /usr/bin/make; - buildWorkingDirectory = /llvm/obj/; + buildWorkingDirectory = ../../obj; dependencies = ( ); name = LLVM; @@ -2323,11 +2422,192 @@ projectDirPath = ""; targets = ( D28A88AD04BDD90700651E21 /* LLVM */, + CF0329B608D1BE110030FD33 /* LLVM lib */, + CF0329BB08D1BE5D0030FD33 /* LLVM llc */, + CF0329BC08D1BE8E0030FD33 /* LLVM full llc */, ); }; /* End PBXProject section */ +/* Begin PBXTargetDependency section */ + CF0329BE08D1BE970030FD33 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CF0329B608D1BE110030FD33 /* LLVM lib */; + targetProxy = CF0329BD08D1BE970030FD33 /* PBXContainerItemProxy */; + }; + CF0329C008D1BE9B0030FD33 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CF0329BB08D1BE5D0030FD33 /* LLVM llc */; + targetProxy = CF0329BF08D1BE9B0030FD33 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ + CF0329B808D1BE530030FD33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM lib"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Debug; + }; + CF0329B908D1BE530030FD33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM lib"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Release; + }; + CF0329BA08D1BE530030FD33 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM lib"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + CF0329C408D1BEC40030FD33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Debug; + }; + CF0329C508D1BEC40030FD33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Release; + }; + CF0329C608D1BEC40030FD33 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + CF0329C808D1BEC40030FD33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM full llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Debug; + }; + CF0329C908D1BEC40030FD33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM full llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Release; + }; + CF0329CA08D1BEC40030FD33 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "LLVM full llc"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; DE66EC4D08ABE78900323D32 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2388,6 +2668,33 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + CF0329B708D1BE530030FD33 /* Build configuration list for PBXLegacyTarget "LLVM lib" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CF0329B808D1BE530030FD33 /* Debug */, + CF0329B908D1BE530030FD33 /* Release */, + CF0329BA08D1BE530030FD33 /* Default */, + ); + defaultConfigurationIsVisible = 0; + }; + CF0329C308D1BEC40030FD33 /* Build configuration list for PBXLegacyTarget "LLVM llc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CF0329C408D1BEC40030FD33 /* Debug */, + CF0329C508D1BEC40030FD33 /* Release */, + CF0329C608D1BEC40030FD33 /* Default */, + ); + defaultConfigurationIsVisible = 0; + }; + CF0329C708D1BEC40030FD33 /* Build configuration list for PBXAggregateTarget "LLVM full llc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CF0329C808D1BEC40030FD33 /* Debug */, + CF0329C908D1BEC40030FD33 /* Release */, + CF0329CA08D1BEC40030FD33 /* Default */, + ); + defaultConfigurationIsVisible = 0; + }; DE66EC4C08ABE78900323D32 /* Build configuration list for PBXLegacyTarget "LLVM" */ = { isa = XCConfigurationList; buildConfigurations = ( From lattner at cs.uiuc.edu Fri Sep 9 13:17:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 13:17:52 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td PPC32InstrInfo.h PPC32InstrInfo.cpp Message-ID: <200509091817.NAA30583@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.96 -> 1.97 PPC32InstrInfo.h updated: 1.2 -> 1.3 PPC32InstrInfo.cpp updated: 1.4 -> 1.5 --- Log message: Teach the code generator that rlwimi is commutable if the rotate amount is zero. This lets the register allocator elide some copies in some cases. This implements CodeGen/PowerPC/rlwimi-commute.ll --- Diffs of the changes: (+38 -1) PPC32InstrInfo.cpp | 32 ++++++++++++++++++++++++++++++++ PPC32InstrInfo.h | 4 ++++ PowerPCInstrInfo.td | 3 ++- 3 files changed, 38 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.96 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.97 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.96 Thu Sep 8 19:39:56 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Fri Sep 9 13:17:41 2005 @@ -733,7 +733,8 @@ // M-Form instructions. rotate and mask instructions. // -let isTwoAddress = 1 in { +let isTwoAddress = 1, isCommutable = 1 in { +// RLWIMI can be commuted if the rotate amount is zero. def RLWIMI : MForm_2<20, (ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME">; Index: llvm/lib/Target/PowerPC/PPC32InstrInfo.h diff -u llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.2 llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.3 --- llvm/lib/Target/PowerPC/PPC32InstrInfo.h:1.2 Thu Apr 21 18:20:02 2005 +++ llvm/lib/Target/PowerPC/PPC32InstrInfo.h Fri Sep 9 13:17:41 2005 @@ -38,6 +38,10 @@ unsigned& sourceReg, unsigned& destReg) const; + // commuteInstruction - We can commute rlwimi instructions, but only if the + // rotate amt is zero. We also have to munge the immediates a bit. + virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + static unsigned invertPPCBranchOpcode(unsigned Opcode) { switch (Opcode) { default: assert(0 && "Unknown PPC branch opcode!"); Index: llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp:1.4 llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp:1.5 --- llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp:1.4 Thu Apr 21 18:20:02 2005 +++ llvm/lib/Target/PowerPC/PPC32InstrInfo.cpp Fri Sep 9 13:17:41 2005 @@ -76,3 +76,35 @@ } return false; } + +// commuteInstruction - We can commute rlwimi instructions, but only if the +// rotate amt is zero. We also have to munge the immediates a bit. +MachineInstr *PPC32InstrInfo::commuteInstruction(MachineInstr *MI) const { + // Normal instructions can be commuted the obvious way. + if (MI->getOpcode() != PPC::RLWIMI) + return TargetInstrInfo::commuteInstruction(MI); + + // Cannot commute if it has a non-zero rotate count. + if (MI->getOperand(3).getImmedValue() != 0) + return 0; + + // If we have a zero rotate count, we have: + // M = mask(MB,ME) + // Op0 = (Op1 & ~M) | (Op2 & M) + // Change this to: + // M = mask((ME+1)&31, (MB-1)&31) + // Op0 = (Op2 & ~M) | (Op1 & M) + + // Swap op1/op2 + unsigned Reg1 = MI->getOperand(1).getReg(); + unsigned Reg2 = MI->getOperand(2).getReg(); + MI->SetMachineOperandReg(2, Reg1); + MI->SetMachineOperandReg(1, Reg2); + + // Swap the mask around. + unsigned MB = MI->getOperand(4).getImmedValue(); + unsigned ME = MI->getOperand(5).getImmedValue(); + MI->getOperand(4).setImmedValue((ME+1) & 31); + MI->getOperand(5).setImmedValue((MB-1) & 31); + return MI; +} From lattner at cs.uiuc.edu Fri Sep 9 14:17:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 14:17:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200509091917.OAA00611@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.146 -> 1.147 --- Log message: When spilling a live range that is used multiple times by one instruction, only add a reload live range once for the instruction. This is one step towards fixing a regalloc pessimization that Nate notice, but is later undone by the spiller (so no code is changed). --- Diffs of the changes: (+26 -9) LiveIntervalAnalysis.cpp | 35 ++++++++++++++++++++++++++--------- 1 files changed, 26 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.146 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.147 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.146 Wed Sep 7 12:34:39 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Sep 9 14:17:47 2005 @@ -249,14 +249,26 @@ MachineBasicBlock::iterator mi = getInstructionFromIndex(index); + // NewRegLiveIn - This instruction might have multiple uses of the spilled + // register. In this case, for the first use, keep track of the new vreg + // that we reload it into. If we see a second use, reuse this vreg + // instead of creating live ranges for two reloads. + unsigned NewRegLiveIn = 0; + for_operand: for (unsigned i = 0; i != mi->getNumOperands(); ++i) { MachineOperand& mop = mi->getOperand(i); if (mop.isRegister() && mop.getReg() == li.reg) { - // First thing, attempt to fold the memory reference into the - // instruction. If we can do this, we don't need to insert spill - // code. - if (MachineInstr* fmi = mri_->foldMemoryOperand(mi, i, slot)) { + if (NewRegLiveIn && mop.isUse()) { + // We already emitted a reload of this value, reuse it for + // subsequent operands. + mi->SetMachineOperandReg(i, NewRegLiveIn); + DEBUG(std::cerr << "\t\t\t\treused reload into reg" << NewRegLiveIn + << " for operand #" << i << '\n'); + mi->dump(); + } else if (MachineInstr* fmi = mri_->foldMemoryOperand(mi, i, slot)) { + // Attempt to fold the memory reference into the instruction. If we + // can do this, we don't need to insert spill code. if (lv_) lv_->instructionChanged(mi, fmi); vrm.virtFolded(li.reg, mi, i, fmi); @@ -288,11 +300,11 @@ getUseIndex(index)); // create a new register for this spill - unsigned nReg = mf_->getSSARegMap()->createVirtualRegister(rc); - mi->SetMachineOperandReg(i, nReg); + NewRegLiveIn = mf_->getSSARegMap()->createVirtualRegister(rc); + mi->SetMachineOperandReg(i, NewRegLiveIn); vrm.grow(); - vrm.assignVirt2StackSlot(nReg, slot); - LiveInterval& nI = getOrCreateInterval(nReg); + vrm.assignVirt2StackSlot(NewRegLiveIn, slot); + LiveInterval& nI = getOrCreateInterval(NewRegLiveIn); assert(nI.empty()); // the spill weight is now infinity as it @@ -305,7 +317,12 @@ // update live variables if it is available if (lv_) - lv_->addVirtualRegisterKilled(nReg, mi); + lv_->addVirtualRegisterKilled(NewRegLiveIn, mi); + + // If this is a live in, reuse it for subsequent live-ins. If it's + // a def, we can't do this. + if (!mop.isUse()) NewRegLiveIn = 0; + DEBUG(std::cerr << "\t\t\t\tadded new interval: " << nI << '\n'); } } From lattner at cs.uiuc.edu Fri Sep 9 14:19:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 14:19:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200509091919.OAA00674@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.147 -> 1.148 --- Log message: remove debugging code *slaps head* --- Diffs of the changes: (+0 -1) LiveIntervalAnalysis.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.147 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.148 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.147 Fri Sep 9 14:17:47 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Sep 9 14:19:20 2005 @@ -265,7 +265,6 @@ mi->SetMachineOperandReg(i, NewRegLiveIn); DEBUG(std::cerr << "\t\t\t\treused reload into reg" << NewRegLiveIn << " for operand #" << i << '\n'); - mi->dump(); } else if (MachineInstr* fmi = mri_->foldMemoryOperand(mi, i, slot)) { // Attempt to fold the memory reference into the instruction. If we // can do this, we don't need to insert spill code. From natebegeman at mac.com Fri Sep 9 14:50:03 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 9 Sep 2005 14:50:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp SelectionDAG.cpp Message-ID: <200509091950.OAA01507@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.9 -> 1.10 SelectionDAG.cpp updated: 1.189 -> 1.190 --- Log message: Last round of 2-node folds from SD.cpp. Will move on to 3 node ops such as setcc and select next. --- Diffs of the changes: (+107 -2) DAGCombiner.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ SelectionDAG.cpp | 6 ++- 2 files changed, 107 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.9 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.10 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.9 Thu Sep 8 15:18:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Sep 9 14:49:52 2005 @@ -574,6 +574,7 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); + SDOperand LL, LR, RL, RR, CC0, CC1; ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); @@ -620,12 +621,60 @@ if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) return N1; + // fold (and (setcc x), (setcc y)) -> (setcc (and x, y)) + if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ + ISD::CondCode Op0 = cast(CC0)->get(); + ISD::CondCode Op1 = cast(CC1)->get(); + + if (LR == RR && isa(LR) && Op0 == Op1 && + MVT::isInteger(LL.getValueType())) { + // fold (X == 0) & (Y == 0) -> (X|Y == 0) + if (cast(LR)->getValue() == 0 && Op1 == ISD::SETEQ) { + SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + WorkList.push_back(ORNode.Val); + return DAG.getSetCC(VT, ORNode, LR, Op1); + } + // fold (X == -1) & (Y == -1) -> (X&Y == -1) + if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETEQ) { + SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); + WorkList.push_back(ANDNode.Val); + return DAG.getSetCC(VT, ANDNode, LR, Op1); + } + // fold (X > -1) & (Y > -1) -> (X|Y > -1) + if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETGT) { + SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + WorkList.push_back(ORNode.Val); + return DAG.getSetCC(VT, ORNode, LR, Op1); + } + } + // canonicalize equivalent to ll == rl + if (LL == RR && LR == RL) { + Op1 = ISD::getSetCCSwappedOperands(Op1); + std::swap(RL, RR); + } + if (LL == RL && LR == RR) { + bool isInteger = MVT::isInteger(LL.getValueType()); + ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger); + if (Result != ISD::SETCC_INVALID) + return DAG.getSetCC(N0.getValueType(), LL, LR, Result); + } + } + // fold (and (zext x), (zext y)) -> (zext (and x, y)) + if (N0.getOpcode() == ISD::ZERO_EXTEND && + N1.getOpcode() == ISD::ZERO_EXTEND && + N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { + SDOperand ANDNode = DAG.getNode(ISD::AND, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(ANDNode.Val); + return DAG.getNode(ISD::ZERO_EXTEND, VT, ANDNode); + } return SDOperand(); } SDOperand DAGCombiner::visitOR(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); + SDOperand LL, LR, RL, RR, CC0, CC1; ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); @@ -661,6 +710,51 @@ return DAG.getNode(ISD::OR, VT, N0.getOperand(0), DAG.getConstant(N1C->getValue()|N01C->getValue(), VT)); } + // fold (or (setcc x), (setcc y)) -> (setcc (or x, y)) + if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ + ISD::CondCode Op0 = cast(CC0)->get(); + ISD::CondCode Op1 = cast(CC1)->get(); + + if (LR == RR && isa(LR) && Op0 == Op1 && + MVT::isInteger(LL.getValueType())) { + // fold (X != 0) | (Y != 0) -> (X|Y != 0) + // fold (X < 0) | (Y < 0) -> (X|Y < 0) + if (cast(LR)->getValue() == 0 && + (Op1 == ISD::SETNE || Op1 == ISD::SETLT)) { + SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + WorkList.push_back(ORNode.Val); + return DAG.getSetCC(VT, ORNode, LR, Op1); + } + // fold (X != -1) | (Y != -1) -> (X&Y != -1) + // fold (X > -1) | (Y > -1) -> (X&Y > -1) + if (cast(LR)->isAllOnesValue() && + (Op1 == ISD::SETNE || Op1 == ISD::SETGT)) { + SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); + WorkList.push_back(ANDNode.Val); + return DAG.getSetCC(VT, ANDNode, LR, Op1); + } + } + // canonicalize equivalent to ll == rl + if (LL == RR && LR == RL) { + Op1 = ISD::getSetCCSwappedOperands(Op1); + std::swap(RL, RR); + } + if (LL == RL && LR == RR) { + bool isInteger = MVT::isInteger(LL.getValueType()); + ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger); + if (Result != ISD::SETCC_INVALID) + return DAG.getSetCC(N0.getValueType(), LL, LR, Result); + } + } + // fold (or (zext x), (zext y)) -> (zext (or x, y)) + if (N0.getOpcode() == ISD::ZERO_EXTEND && + N1.getOpcode() == ISD::ZERO_EXTEND && + N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { + SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(ORNode.Val); + return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode); + } return SDOperand(); } @@ -733,6 +827,15 @@ // fold (xor x, x) -> 0 if (N0 == N1) return DAG.getConstant(0, VT); + // fold (xor (zext x), (zext y)) -> (zext (xor x, y)) + if (N0.getOpcode() == ISD::ZERO_EXTEND && + N1.getOpcode() == ISD::ZERO_EXTEND && + N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { + SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(XORNode.Val); + return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode); + } return SDOperand(); } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.189 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.190 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.189 Thu Sep 8 15:18:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Sep 9 14:49:52 2005 @@ -1310,10 +1310,10 @@ } } + if (!CombinerEnabled) { if (N2C) { uint64_t C2 = N2C->getValue(); - if (!CombinerEnabled) { switch (Opcode) { case ISD::ADD: if (!C2) return N1; // add X, 0 -> X @@ -1486,7 +1486,7 @@ if (ConstantSDNode *N3C = dyn_cast(N1.Val->getOperand(1))) return getNode(Opcode, VT, N1.Val->getOperand(0), getNode(Opcode, VT, N2, N1.Val->getOperand(1))); - } + } } ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); @@ -1533,6 +1533,7 @@ case ISD::AND: case ISD::OR: + if (!CombinerEnabled) { if (N1.Val->getOpcode() == ISD::SETCC && N2.Val->getOpcode() == ISD::SETCC){ SDNode *LHS = N1.Val, *RHS = N2.Val; SDOperand LL = LHS->getOperand(0), RL = RHS->getOperand(0); @@ -1595,6 +1596,7 @@ return getNode(ISD::ZERO_EXTEND, VT, getNode(Opcode, N1.getOperand(0).getValueType(), N1.getOperand(0), N2.getOperand(0))); + } break; case ISD::XOR: if (!CombinerEnabled) { From lattner at cs.uiuc.edu Fri Sep 9 15:30:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 15:30:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200509092030.PAA03389@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.37 -> 1.38 --- Log message: Use continue in the use-processing loop to make it clear what the early exits are, simplify logic, and cause things to not be nested as deeply. This also uses MRI->areAliases instead of an explicit loop. No functionality change, just code cleanup. --- Diffs of the changes: (+122 -114) VirtRegMap.cpp | 236 +++++++++++++++++++++++++++++---------------------------- 1 files changed, 122 insertions(+), 114 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.37 llvm/lib/CodeGen/VirtRegMap.cpp:1.38 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.37 Thu Apr 21 17:33:33 2005 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Sep 9 15:29:51 2005 @@ -314,129 +314,137 @@ // Process all of the spilled uses and all non spilled reg references. for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); - if (MO.isRegister() && MO.getReg() && - MRegisterInfo::isPhysicalRegister(MO.getReg())) + if (!MO.isRegister() || MO.getReg() == 0) + continue; // Ignore non-register operands. + + if (MRegisterInfo::isPhysicalRegister(MO.getReg())) { + // Ignore physregs for spilling, but remember that it is used by this + // function. PhysRegsUsed[MO.getReg()] = true; - else if (MO.isRegister() && MO.getReg() && - MRegisterInfo::isVirtualRegister(MO.getReg())) { - unsigned VirtReg = MO.getReg(); - - if (!VRM.hasStackSlot(VirtReg)) { - // This virtual register was assigned a physreg! - unsigned Phys = VRM.getPhys(VirtReg); - PhysRegsUsed[Phys] = true; - MI.SetMachineOperandReg(i, Phys); - } else { - // Is this virtual register a spilled value? - if (MO.isUse()) { - int StackSlot = VRM.getStackSlot(VirtReg); - unsigned PhysReg; - - // Check to see if this stack slot is available. - std::map::iterator SSI = - SpillSlotsAvailable.find(StackSlot); - if (SSI != SpillSlotsAvailable.end()) { - DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " - << MRI->getName(SSI->second) << " for vreg" - << VirtReg <<" instead of reloading into physreg " - << MRI->getName(VRM.getPhys(VirtReg)) << "\n"); - // If this stack slot value is already available, reuse it! - PhysReg = SSI->second; - MI.SetMachineOperandReg(i, PhysReg); - - // The only technical detail we have is that we don't know that - // PhysReg won't be clobbered by a reloaded stack slot that occurs - // later in the instruction. In particular, consider 'op V1, V2'. - // If V1 is available in physreg R0, we would choose to reuse it - // here, instead of reloading it into the register the allocator - // indicated (say R1). However, V2 might have to be reloaded - // later, and it might indicate that it needs to live in R0. When - // this occurs, we need to have information available that - // indicates it is safe to use R1 for the reload instead of R0. - // - // To further complicate matters, we might conflict with an alias, - // or R0 and R1 might not be compatible with each other. In this - // case, we actually insert a reload for V1 in R1, ensuring that - // we can get at R0 or its alias. - ReusedOperands.push_back(ReusedOp(i, StackSlot, PhysReg, - VRM.getPhys(VirtReg))); - ++NumReused; - } else { - // Otherwise, reload it and remember that we have it. - PhysReg = VRM.getPhys(VirtReg); - - RecheckRegister: - // Note that, if we reused a register for a previous operand, the - // register we want to reload into might not actually be - // available. If this occurs, use the register indicated by the - // reuser. - if (!ReusedOperands.empty()) // This is most often empty. - for (unsigned ro = 0, e = ReusedOperands.size(); ro != e; ++ro) - if (ReusedOperands[ro].PhysRegReused == PhysReg) { - // Yup, use the reload register that we didn't use before. - PhysReg = ReusedOperands[ro].AssignedPhysReg; - goto RecheckRegister; - } else { - ReusedOp &Op = ReusedOperands[ro]; - unsigned PRRU = Op.PhysRegReused; - for (const unsigned *AS = MRI->getAliasSet(PRRU); *AS; ++AS) - if (*AS == PhysReg) { - // Okay, we found out that an alias of a reused register - // was used. This isn't good because it means we have - // to undo a previous reuse. - MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg, - Op.StackSlot); - ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable, - PhysRegsAvailable); - - // Any stores to this stack slot are not dead anymore. - MaybeDeadStores.erase(Op.StackSlot); - - MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); - PhysRegsAvailable[Op.AssignedPhysReg] = Op.StackSlot; - SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg; - PhysRegsAvailable.erase(Op.PhysRegReused); - DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot - << " in physreg " - << MRI->getName(Op.AssignedPhysReg) << "\n"); - ++NumLoads; - DEBUG(std::cerr << '\t' << *prior(MII)); - - DEBUG(std::cerr << "Reuse undone!\n"); - ReusedOperands.erase(ReusedOperands.begin()+ro); - --NumReused; - goto ContinueReload; - } - } - ContinueReload: - PhysRegsUsed[PhysReg] = true; - MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot); - // This invalidates PhysReg. - ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); + continue; + } + + assert(MRegisterInfo::isVirtualRegister(MO.getReg()) && + "Not a virtual or a physical register?"); + + unsigned VirtReg = MO.getReg(); + if (!VRM.hasStackSlot(VirtReg)) { + // This virtual register was assigned a physreg! + unsigned Phys = VRM.getPhys(VirtReg); + PhysRegsUsed[Phys] = true; + MI.SetMachineOperandReg(i, Phys); + continue; + } + + // This virtual register is now known to be a spilled value. + if (!MO.isUse()) + continue; // Handle defs in the loop below (handle use&def here though) + + // If this is both a def and a use, we need to emit a store to the + // stack slot after the instruction. Keep track of D&U operands + // because we are about to change it to a physreg here. + if (MO.isDef()) { + // Remember that this was a def-and-use operand, and that the + // stack slot is live after this instruction executes. + DefAndUseVReg.push_back(std::make_pair(i, VirtReg)); + } + + int StackSlot = VRM.getStackSlot(VirtReg); + unsigned PhysReg; + + // Check to see if this stack slot is available. + std::map::iterator SSI = + SpillSlotsAvailable.find(StackSlot); + if (SSI != SpillSlotsAvailable.end()) { + DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " + << MRI->getName(SSI->second) << " for vreg" + << VirtReg <<" instead of reloading into physreg " + << MRI->getName(VRM.getPhys(VirtReg)) << "\n"); + // If this stack slot value is already available, reuse it! + PhysReg = SSI->second; + MI.SetMachineOperandReg(i, PhysReg); + + // The only technical detail we have is that we don't know that + // PhysReg won't be clobbered by a reloaded stack slot that occurs + // later in the instruction. In particular, consider 'op V1, V2'. + // If V1 is available in physreg R0, we would choose to reuse it + // here, instead of reloading it into the register the allocator + // indicated (say R1). However, V2 might have to be reloaded + // later, and it might indicate that it needs to live in R0. When + // this occurs, we need to have information available that + // indicates it is safe to use R1 for the reload instead of R0. + // + // To further complicate matters, we might conflict with an alias, + // or R0 and R1 might not be compatible with each other. In this + // case, we actually insert a reload for V1 in R1, ensuring that + // we can get at R0 or its alias. + ReusedOperands.push_back(ReusedOp(i, StackSlot, PhysReg, + VRM.getPhys(VirtReg))); + ++NumReused; + continue; + } + + // Otherwise, reload it and remember that we have it. + PhysReg = VRM.getPhys(VirtReg); + + RecheckRegister: + // Note that, if we reused a register for a previous operand, the + // register we want to reload into might not actually be + // available. If this occurs, use the register indicated by the + // reuser. + if (!ReusedOperands.empty()) // This is most often empty. + for (unsigned ro = 0, e = ReusedOperands.size(); ro != e; ++ro) + if (ReusedOperands[ro].PhysRegReused == PhysReg) { + // Yup, use the reload register that we didn't use before. + PhysReg = ReusedOperands[ro].AssignedPhysReg; + goto RecheckRegister; + } else { + ReusedOp &Op = ReusedOperands[ro]; + unsigned PRRU = Op.PhysRegReused; + if (MRI->areAliases(PRRU, PhysReg)) { + // Okay, we found out that an alias of a reused register + // was used. This isn't good because it means we have + // to undo a previous reuse. + MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg, + Op.StackSlot); + ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable, + PhysRegsAvailable); // Any stores to this stack slot are not dead anymore. - MaybeDeadStores.erase(StackSlot); + MaybeDeadStores.erase(Op.StackSlot); - MI.SetMachineOperandReg(i, PhysReg); - PhysRegsAvailable[PhysReg] = StackSlot; - SpillSlotsAvailable[StackSlot] = PhysReg; - DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg " - << MRI->getName(PhysReg) << "\n"); + MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); + PhysRegsAvailable[Op.AssignedPhysReg] = Op.StackSlot; + SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg; + PhysRegsAvailable.erase(Op.PhysRegReused); + DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot + << " in physreg " + << MRI->getName(Op.AssignedPhysReg) << "\n"); ++NumLoads; DEBUG(std::cerr << '\t' << *prior(MII)); - } - // If this is both a def and a use, we need to emit a store to the - // stack slot after the instruction. Keep track of D&U operands - // because we already changed it to a physreg here. - if (MO.isDef()) { - // Remember that this was a def-and-use operand, and that the - // stack slot is live after this instruction executes. - DefAndUseVReg.push_back(std::make_pair(i, VirtReg)); + DEBUG(std::cerr << "Reuse undone!\n"); + ReusedOperands.erase(ReusedOperands.begin()+ro); + --NumReused; + goto ContinueReload; } } - } - } + ContinueReload: + PhysRegsUsed[PhysReg] = true; + MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot); + // This invalidates PhysReg. + ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); + + // Any stores to this stack slot are not dead anymore. + MaybeDeadStores.erase(StackSlot); + + MI.SetMachineOperandReg(i, PhysReg); + PhysRegsAvailable[PhysReg] = StackSlot; + SpillSlotsAvailable[StackSlot] = PhysReg; + DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg " + << MRI->getName(PhysReg) << "\n"); + ++NumLoads; + DEBUG(std::cerr << '\t' << *prior(MII)); } // Loop over all of the implicit defs, clearing them from our available From lattner at cs.uiuc.edu Fri Sep 9 15:51:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 15:51:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200509092051.PAA03868@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.20 -> 1.21 --- Log message: code cleanup --- Diffs of the changes: (+3 -2) PPC32RegisterInfo.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.20 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.21 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.20 Fri Aug 26 16:51:29 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Fri Sep 9 15:51:08 2005 @@ -214,8 +214,9 @@ // convert into indexed form of the instruction // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0 // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0 - unsigned NewOpcode = const_cast& >(ImmToIdxMap)[MI.getOpcode()]; - assert(NewOpcode && "No indexed form of load or store available!"); + assert(ImmToIdxMap.count(MI.getOpcode()) && + "No indexed form of load or store available!"); + unsigned NewOpcode = ImmToIdxMap.find(MI.getOpcode())->second; MI.setOpcode(NewOpcode); MI.SetMachineOperandReg(1, MI.getOperand(i).getReg()); MI.SetMachineOperandReg(2, PPC::R0); From lattner at cs.uiuc.edu Fri Sep 9 16:47:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 16:47:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp PPC32RegisterInfo.h Message-ID: <200509092147.QAA12642@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.21 -> 1.22 PPC32RegisterInfo.h updated: 1.3 -> 1.4 --- Log message: Fix a problem that Nate noticed, where spill code was not getting coallesced with copies, leading to code like this: lwz r4, 380(r1) or r10, r4, r4 ;; Last use of r4 By teaching the PPC backend how to fold spills into copies, we now get this code: lwz r10, 380(r1) wow. :) This reduces a testcase nate sent me from 1505 instructions to 1484. Note that this could handle FP values but doesn't currently, for reasons mentioned in the patch --- Diffs of the changes: (+32 -0) PPC32RegisterInfo.cpp | 27 +++++++++++++++++++++++++++ PPC32RegisterInfo.h | 5 +++++ 2 files changed, 32 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.21 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.22 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.21 Fri Sep 9 15:51:08 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Fri Sep 9 16:46:49 2005 @@ -134,6 +134,33 @@ } } +/// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into +/// copy instructions, turning them into load/store instructions. +MachineInstr *PPC32RegisterInfo::foldMemoryOperand(MachineInstr *MI, + unsigned OpNum, + int FrameIndex) const { + // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because + // it takes more than one instruction to store it. + unsigned Opc = MI->getOpcode(); + + if ((Opc == PPC::OR && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + return addFrameReference(BuildMI(PPC::STW, + 3).addReg(InReg), FrameIndex); + } else { + unsigned OutReg = MI->getOperand(0).getReg(); + return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex); + } + + } else if (Opc == PPC::FMR) { + // FIXME: We would be able to fold this, but we don't know whether to use a + // 32- or 64-bit load/store :(. + } + return 0; +} + //===----------------------------------------------------------------------===// // Stack Frame Processing methods //===----------------------------------------------------------------------===// Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.h diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.3 llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.4 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.h:1.3 Fri Aug 19 13:30:39 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.h Fri Sep 9 16:46:49 2005 @@ -40,6 +40,11 @@ unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into + /// copy instructions, turning them into load/store instructions. + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, + int FrameIndex) const; + void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; From lattner at cs.uiuc.edu Fri Sep 9 16:59:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 16:59:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200509092159.QAA18402@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.22 -> 1.23 --- Log message: I forgot that we always spill fp values as 64-bits. Implement spill folding for FP as well. This triggers a couple dozen times on 177.mesa (for example). --- Diffs of the changes: (+10 -3) PPC32RegisterInfo.cpp | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.22 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.23 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.22 Fri Sep 9 16:46:49 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Fri Sep 9 16:59:44 2005 @@ -149,14 +149,21 @@ unsigned InReg = MI->getOperand(1).getReg(); return addFrameReference(BuildMI(PPC::STW, 3).addReg(InReg), FrameIndex); - } else { + } else { // move -> load unsigned OutReg = MI->getOperand(0).getReg(); return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex); } } else if (Opc == PPC::FMR) { - // FIXME: We would be able to fold this, but we don't know whether to use a - // 32- or 64-bit load/store :(. + // We currently always spill FP values as doubles. :( + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + return addFrameReference(BuildMI(PPC::STFD, + 3).addReg(InReg), FrameIndex); + } else { // move -> load + unsigned OutReg = MI->getOperand(0).getReg(); + return addFrameReference(BuildMI(PPC::LFD, 2, OutReg), FrameIndex); + } } return 0; } From lattner at cs.uiuc.edu Fri Sep 9 17:35:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 17:35:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509092235.RAA05445@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.190 -> 1.191 --- Log message: Fix a crash viewing dags that have target nodes in them --- Diffs of the changes: (+2 -1) SelectionDAG.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.190 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.191 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.190 Fri Sep 9 14:49:52 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Sep 9 17:35:03 2005 @@ -2263,7 +2263,8 @@ else { if (G) if (const TargetInstrInfo *TII = G->getTarget().getInstrInfo()) - return TII->getName(getOpcode()-ISD::BUILTIN_OP_END); + if (getOpcode()-ISD::BUILTIN_OP_END < TII->getNumOpcodes()) + return TII->getName(getOpcode()-ISD::BUILTIN_OP_END); return "<>"; } From lattner at cs.uiuc.edu Fri Sep 9 18:00:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 18:00:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509092300.SAA06147@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.191 -> 1.192 --- Log message: Fix a problem duraid encountered on itanium where this folding: select (x < y), 1, 0 -> (x < y) incorrectly: the setcc returns i1 but the select returned i32. Add the zero extend as needed. --- Diffs of the changes: (+6 -2) SelectionDAG.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.191 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.192 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.191 Fri Sep 9 17:35:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Sep 9 18:00:07 2005 @@ -974,8 +974,12 @@ // Check to see if this is the equivalent of setcc if (N4C && N4C->isNullValue() && N3C && (N3C->getValue() == 1ULL)) { MVT::ValueType XType = N1.getValueType(); - if (TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultTy())) - return getSetCC(TLI.getSetCCResultTy(), N1, N2, CC); + if (TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultTy())) { + SDOperand Res = getSetCC(TLI.getSetCCResultTy(), N1, N2, CC); + if (Res.getValueType() != VT) + Res = getNode(ISD::ZERO_EXTEND, VT, Res); + return Res; + } // seteq X, 0 -> srl (ctlz X, log2(size(X))) if (N2C && N2C->isNullValue() && CC == ISD::SETEQ && From lattner at cs.uiuc.edu Fri Sep 9 18:53:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 18:53:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200509092353.SAA07067@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.10 -> 1.11 --- Log message: Add a missing #include, patch courtesy of Baptiste Lepilleur. --- Diffs of the changes: (+1 -0) DAGCombiner.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.10 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.11 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.10 Fri Sep 9 14:49:52 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Sep 9 18:53:39 2005 @@ -40,6 +40,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetLowering.h" +#include #include using namespace llvm; From lattner at cs.uiuc.edu Fri Sep 9 19:20:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 19:20:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200509100020.TAA07648@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.185 -> 1.186 --- Log message: Allow targets to say they don't support truncstore i1 (which includes a mask when storing to an 8-bit memory location), as most don't. --- Diffs of the changes: (+15 -2) LegalizeDAG.cpp | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.185 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.186 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.185 Fri Sep 2 15:32:45 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Sep 9 19:20:18 2005 @@ -1043,10 +1043,23 @@ switch (getTypeAction(Node->getOperand(1).getValueType())) { case Legal: Tmp2 = LegalizeOp(Node->getOperand(1)); - if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) || - Tmp3 != Node->getOperand(2)) + + // The only promote case we handle is TRUNCSTORE:i1 X into + // -> TRUNCSTORE:i8 (and X, 1) + if (cast(Node->getOperand(4))->getVT() == MVT::i1 && + TLI.getOperationAction(ISD::TRUNCSTORE, MVT::i1) == + TargetLowering::Promote) { + // Promote the bool to a mask then store. + Tmp2 = DAG.getNode(ISD::AND, Tmp2.getValueType(), Tmp2, + DAG.getConstant(1, Tmp2.getValueType())); + Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3, + Node->getOperand(3), DAG.getValueType(MVT::i8)); + + } else if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) || + Tmp3 != Node->getOperand(2)) { Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3, Node->getOperand(3), Node->getOperand(4)); + } break; case Promote: case Expand: From lattner at cs.uiuc.edu Fri Sep 9 19:21:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 19:21:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC32ISelLowering.cpp PPC32ISelDAGToDAG.cpp Message-ID: <200509100021.TAA07690@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.177 -> 1.178 PPC32ISelLowering.cpp updated: 1.22 -> 1.23 PPC32ISelDAGToDAG.cpp updated: 1.74 -> 1.75 --- Log message: PowerPC cannot truncstore i1 natively --- Diffs of the changes: (+3 -2) PPC32ISelDAGToDAG.cpp | 1 - PPC32ISelLowering.cpp | 3 +++ PPC32ISelPattern.cpp | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.177 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.178 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.177 Tue Sep 6 17:03:27 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Sep 9 19:21:05 2005 @@ -1795,7 +1795,6 @@ } else { //ISD::TRUNCSTORE switch(cast(Node->getOperand(4))->getVT()) { default: assert(0 && "unknown Type in store"); - case MVT::i1: case MVT::i8: Opc = PPC::STB; break; case MVT::i16: Opc = PPC::STH; break; } Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.22 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.23 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.22 Tue Sep 6 17:03:27 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Fri Sep 9 19:21:05 2005 @@ -91,6 +91,9 @@ setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand); setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); + // PowerPC does not have truncstore for i1. + setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); + // 64 bit PowerPC implementations have instructions to facilitate conversion // between i64 and fp. if (TM.getSubtarget().is64Bit()) { Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.74 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.75 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.74 Wed Sep 7 18:45:15 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Fri Sep 9 19:21:06 2005 @@ -1263,7 +1263,6 @@ } else { //ISD::TRUNCSTORE switch(cast(N->getOperand(4))->getVT()) { default: assert(0 && "unknown Type in store"); - case MVT::i1: case MVT::i8: Opc = isIdx ? PPC::STBX : PPC::STB; break; case MVT::i16: Opc = isIdx ? PPC::STHX : PPC::STH; break; } From lattner at cs.uiuc.edu Fri Sep 9 20:14:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 20:14:48 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll Message-ID: <200509100114.UAA08015@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopStrengthReduce: dont-hoist-simple-loop-constants.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+24 -0) dont-hoist-simple-loop-constants.ll | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+) Index: llvm/test/Regression/Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll diff -c /dev/null llvm/test/Regression/Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll:1.1 *** /dev/null Fri Sep 9 20:14:47 2005 --- llvm/test/Regression/Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll Fri Sep 9 20:14:37 2005 *************** *** 0 **** --- 1,24 ---- + ; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | not grep 'cast uint 1 to uint' + ; The setlt wants to use a value that is incremented one more than the dominant + ; IV. Don't insert the 1 outside the loop, preventing folding it into the add. + + implementation ; Functions: + + void %test([700 x int]* %nbeaux_.0__558, int* %i_.16574) { + then.0: + br label %no_exit.2 + + no_exit.2: ; preds = %no_exit.2, %then.0 + %indvar630 = phi uint [ 0, %then.0 ], [ %indvar.next631, %no_exit.2 ] ; [#uses=3] + %indvar630 = cast uint %indvar630 to int ; [#uses=1] + %tmp.38 = getelementptr [700 x int]* %nbeaux_.0__558, int 0, uint %indvar630 ; [#uses=1] + store int 0, int* %tmp.38 + %inc.2 = add int %indvar630, 2 ; [#uses=2] + %tmp.34 = setlt int %inc.2, 701 ; [#uses=1] + %indvar.next631 = add uint %indvar630, 1 ; [#uses=1] + br bool %tmp.34, label %no_exit.2, label %loopexit.2.loopexit + + loopexit.2.loopexit: ; preds = %no_exit.2 + store int %inc.2, int* %i_.16574 + ret void + } From lattner at cs.uiuc.edu Fri Sep 9 20:18:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 9 Sep 2005 20:18:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200509100118.UAA08057@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.54 -> 1.55 --- Log message: implement Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll. We used to emit this code for it: _test: li r2, 1 ;; Value tying up a register for the whole loop li r5, 0 LBB_test_1: ; no_exit.2 or r6, r5, r5 li r5, 0 stw r5, 0(r3) addi r5, r6, 1 addi r3, r3, 4 add r7, r2, r5 ;; should be addi r7, r5, 1 cmpwi cr0, r7, 701 blt cr0, LBB_test_1 ; no_exit.2 LBB_test_2: ; loopexit.2.loopexit addi r2, r6, 2 stw r2, 0(r4) blr now we emit this: _test: li r2, 0 LBB_test_1: ; no_exit.2 or r5, r2, r2 li r2, 0 stw r2, 0(r3) addi r3, r3, 4 addi r2, r5, 1 addi r6, r5, 2 ;; whoa, fold those adds! cmpwi cr0, r6, 701 blt cr0, LBB_test_1 ; no_exit.2 LBB_test_2: ; loopexit.2.loopexit addi r2, r5, 2 stw r2, 0(r4) blr more improvement coming. --- Diffs of the changes: (+1 -1) LoopStrengthReduce.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.54 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.55 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.54 Wed Aug 17 16:22:41 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri Sep 9 20:18:45 2005 @@ -826,7 +826,7 @@ // this by forcing a noop cast to be inserted into the preheader in this // case. if (Constant *C = dyn_cast(BaseV)) - if (!C->isNullValue()) { + if (!C->isNullValue() && !isTargetConstant(Base)) { // We want this constant emitted into the preheader! BaseV = new CastInst(BaseV, BaseV->getType(), "preheaderinsert", PreInsertPt); From jeffc at jolt-lang.org Fri Sep 9 21:00:14 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 9 Sep 2005 21:00:14 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.h Message-ID: <200509100200.VAA08236@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.h updated: 1.7 -> 1.8 --- Log message: Fix miscellaneous Visual Studio build problems. --- Diffs of the changes: (+1 -1) DAGISelEmitter.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.7 llvm/utils/TableGen/DAGISelEmitter.h:1.8 --- llvm/utils/TableGen/DAGISelEmitter.h:1.7 Thu Sep 8 20:15:01 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Fri Sep 9 21:00:02 2005 @@ -19,7 +19,7 @@ namespace llvm { class Record; - class Init; + struct Init; class DagInit; class SDNodeInfo; class TreePattern; From jeffc at jolt-lang.org Fri Sep 9 21:00:14 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 9 Sep 2005 21:00:14 -0500 Subject: [llvm-commits] CVS: llvm/win32/TableGen/TableGen.vcproj Message-ID: <200509100200.VAA08230@zion.cs.uiuc.edu> Changes in directory llvm/win32/TableGen: TableGen.vcproj updated: 1.13 -> 1.14 --- Log message: Fix miscellaneous Visual Studio build problems. --- Diffs of the changes: (+6 -0) TableGen.vcproj | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/win32/TableGen/TableGen.vcproj diff -u llvm/win32/TableGen/TableGen.vcproj:1.13 llvm/win32/TableGen/TableGen.vcproj:1.14 --- llvm/win32/TableGen/TableGen.vcproj:1.13 Wed Feb 2 00:33:11 2005 +++ llvm/win32/TableGen/TableGen.vcproj Fri Sep 9 21:00:02 2005 @@ -133,6 +133,9 @@ RelativePath="..\..\utils\TableGen\CodeGenTarget.cpp"> + + @@ -215,6 +218,9 @@ RelativePath="..\..\utils\TableGen\CodeGenTarget.h"> + + Changes in directory llvm/win32: llvm.sln updated: 1.24 -> 1.25 --- Log message: Fix miscellaneous Visual Studio build problems. --- Diffs of the changes: (+2 -0) llvm.sln | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.24 llvm/win32/llvm.sln:1.25 --- llvm/win32/llvm.sln:1.24 Sat Jan 22 11:35:30 2005 +++ llvm/win32/llvm.sln Fri Sep 9 21:00:02 2005 @@ -76,6 +76,7 @@ {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} {76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A} {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} @@ -93,6 +94,7 @@ {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} {057777CD-DED5-46DF-BF9A-6B76DE212549} = {057777CD-DED5-46DF-BF9A-6B76DE212549} {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} From jeffc at jolt-lang.org Fri Sep 9 21:33:28 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 9 Sep 2005 21:33:28 -0500 Subject: [llvm-commits] CVS: llvm/win32/CodeGen/CodeGen.vcproj Message-ID: <200509100233.VAA08382@zion.cs.uiuc.edu> Changes in directory llvm/win32/CodeGen: CodeGen.vcproj updated: 1.12 -> 1.13 --- Log message: Fix more Visual Studio build problems. --- Diffs of the changes: (+6 -0) CodeGen.vcproj | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/win32/CodeGen/CodeGen.vcproj diff -u llvm/win32/CodeGen/CodeGen.vcproj:1.12 llvm/win32/CodeGen/CodeGen.vcproj:1.13 --- llvm/win32/CodeGen/CodeGen.vcproj:1.12 Mon Jun 27 21:43:03 2005 +++ llvm/win32/CodeGen/CodeGen.vcproj Fri Sep 9 21:33:17 2005 @@ -176,9 +176,15 @@ Name="SelectionDAG" Filter=""> + + + + Changes in directory llvm/test/Regression/CodeGen/PowerPC: 2005-09-02-LegalizeDuplicatesCalls.ll updated: 1.1 -> 1.2 --- Log message: Make sure to disable 64-bit extensions for this test --- Diffs of the changes: (+1 -1) 2005-09-02-LegalizeDuplicatesCalls.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll diff -u llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll:1.1 llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll:1.2 --- llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll:1.1 Fri Sep 2 15:24:10 2005 +++ llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll Sat Sep 10 22:50:38 2005 @@ -1,6 +1,6 @@ ; This function should have exactly one call to fixdfdi, no more! -; RUN: llvm-as < %s | llc -march=ppc32 | grep 'bl .*fixdfdi' | wc -l | grep 1 +; RUN: llvm-as < %s | llc -march=ppc32 -mattr=-64bit | grep 'bl .*fixdfdi' | wc -l | grep 1 double %test2(double %tmp.7705) { %mem_tmp.2.0.in = cast double %tmp.7705 to long ; [#uses=1]