[llvm-commits] [llvm] r72464 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Eli Friedman
eli.friedman at gmail.com
Wed May 27 00:05:38 PDT 2009
Author: efriedma
Date: Wed May 27 02:05:37 2009
New Revision: 72464
URL: http://llvm.org/viewvc/llvm-project?rev=72464&view=rev
Log:
Eliminate more special cases for opcodes.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=72464&r1=72463&r2=72464&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed May 27 02:05:37 2009
@@ -780,8 +780,6 @@
case ISD::MERGE_VALUES:
case ISD::EH_RETURN:
case ISD::FRAME_TO_ARGS_OFFSET:
- case ISD::EXCEPTIONADDR:
- case ISD::EHSELECTION:
// These operations lie about being legal: when they claim to be legal,
// they should actually be expanded.
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
@@ -885,74 +883,6 @@
#endif
assert(0 && "Do not know how to legalize this operator!");
abort();
- case ISD::EXCEPTIONADDR: {
- Tmp1 = LegalizeOp(Node->getOperand(0));
- MVT VT = Node->getValueType(0);
- switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
- default: assert(0 && "This action is not supported yet!");
- case TargetLowering::Expand: {
- unsigned Reg = TLI.getExceptionAddressRegister();
- Result = DAG.getCopyFromReg(Tmp1, dl, Reg, VT);
- }
- break;
- case TargetLowering::Custom:
- Result = TLI.LowerOperation(Op, DAG);
- if (Result.getNode()) break;
- // Fall Thru
- case TargetLowering::Legal: {
- SDValue Ops[] = { DAG.getConstant(0, VT), Tmp1 };
- Result = DAG.getMergeValues(Ops, 2, dl);
- break;
- }
- }
- }
- if (Result.getNode()->getNumValues() == 1) break;
-
- assert(Result.getNode()->getNumValues() == 2 &&
- "Cannot return more than two values!");
-
- // Since we produced two values, make sure to remember that we
- // legalized both of them.
- Tmp1 = LegalizeOp(Result);
- Tmp2 = LegalizeOp(Result.getValue(1));
- AddLegalizedOperand(Op.getValue(0), Tmp1);
- AddLegalizedOperand(Op.getValue(1), Tmp2);
- return Op.getResNo() ? Tmp2 : Tmp1;
- case ISD::EHSELECTION: {
- Tmp1 = LegalizeOp(Node->getOperand(0));
- Tmp2 = LegalizeOp(Node->getOperand(1));
- MVT VT = Node->getValueType(0);
- switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
- default: assert(0 && "This action is not supported yet!");
- case TargetLowering::Expand: {
- unsigned Reg = TLI.getExceptionSelectorRegister();
- Result = DAG.getCopyFromReg(Tmp2, dl, Reg, VT);
- }
- break;
- case TargetLowering::Custom:
- Result = TLI.LowerOperation(Op, DAG);
- if (Result.getNode()) break;
- // Fall Thru
- case TargetLowering::Legal: {
- SDValue Ops[] = { DAG.getConstant(0, VT), Tmp2 };
- Result = DAG.getMergeValues(Ops, 2, dl);
- break;
- }
- }
- }
- if (Result.getNode()->getNumValues() == 1) break;
-
- assert(Result.getNode()->getNumValues() == 2 &&
- "Cannot return more than two values!");
-
- // Since we produced two values, make sure to remember that we
- // legalized both of them.
- Tmp1 = LegalizeOp(Result);
- Tmp2 = LegalizeOp(Result.getValue(1));
- AddLegalizedOperand(Op.getValue(0), Tmp1);
- AddLegalizedOperand(Op.getValue(1), Tmp2);
- return Op.getResNo() ? Tmp2 : Tmp1;
-
case ISD::DBG_STOPPOINT:
assert(Node->getNumOperands() == 1 && "Invalid DBG_STOPPOINT node!");
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the input chain.
@@ -2055,128 +1985,6 @@
break;
// Binary operators
- case ISD::SUB:
- case ISD::MUL:
- case ISD::MULHS:
- case ISD::MULHU:
- case ISD::UDIV:
- case ISD::SDIV:
- Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
- Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS
-
- Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-
- switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
- default: assert(0 && "BinOp legalize operation not supported");
- case TargetLowering::Legal: break;
- case TargetLowering::Custom:
- Tmp1 = TLI.LowerOperation(Result, DAG);
- if (Tmp1.getNode()) {
- Result = Tmp1;
- break;
- }
- // Fall through if the custom lower can't deal with the operation
- case TargetLowering::Expand: {
- MVT VT = Op.getValueType();
-
- // See if multiply or divide can be lowered using two-result operations.
- SDVTList VTs = DAG.getVTList(VT, VT);
- if (Node->getOpcode() == ISD::MUL) {
- // We just need the low half of the multiply; try both the signed
- // and unsigned forms. If the target supports both SMUL_LOHI and
- // UMUL_LOHI, form a preference by checking which forms of plain
- // MULH it supports.
- bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT);
- bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT);
- bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT);
- bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT);
- unsigned OpToUse = 0;
- if (HasSMUL_LOHI && !HasMULHS) {
- OpToUse = ISD::SMUL_LOHI;
- } else if (HasUMUL_LOHI && !HasMULHU) {
- OpToUse = ISD::UMUL_LOHI;
- } else if (HasSMUL_LOHI) {
- OpToUse = ISD::SMUL_LOHI;
- } else if (HasUMUL_LOHI) {
- OpToUse = ISD::UMUL_LOHI;
- }
- if (OpToUse) {
- Result = DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2);
- break;
- }
- }
- if (Node->getOpcode() == ISD::MULHS &&
- TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) {
- Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl,
- VTs, Tmp1, Tmp2).getNode(),
- 1);
- break;
- }
- if (Node->getOpcode() == ISD::MULHU &&
- TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) {
- Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl,
- VTs, Tmp1, Tmp2).getNode(),
- 1);
- break;
- }
- if (Node->getOpcode() == ISD::SDIV &&
- TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) {
- Result = DAG.getNode(ISD::SDIVREM, dl, VTs, Tmp1, Tmp2);
- break;
- }
- if (Node->getOpcode() == ISD::UDIV &&
- TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) {
- Result = DAG.getNode(ISD::UDIVREM, dl, VTs, Tmp1, Tmp2);
- break;
- }
- if (Node->getOpcode() == ISD::SUB &&
- TLI.isOperationLegalOrCustom(ISD::ADD, VT) &&
- TLI.isOperationLegalOrCustom(ISD::XOR, VT)) {
- Tmp2 = DAG.getNode(ISD::XOR, dl, VT, Tmp2,
- DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT));
- Tmp2 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT));
- Result = DAG.getNode(ISD::ADD, dl, VT, Tmp1, Tmp2);
- break;
- }
-
- // Check to see if we have a libcall for this operator.
- RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- bool isSigned = false;
- switch (Node->getOpcode()) {
- case ISD::UDIV:
- case ISD::SDIV:
- isSigned = Node->getOpcode() == ISD::SDIV;
- if (VT == MVT::i16)
- LC = (isSigned ? RTLIB::SDIV_I16 : RTLIB::UDIV_I16);
- else if (VT == MVT::i32)
- LC = (isSigned ? RTLIB::SDIV_I32 : RTLIB::UDIV_I32);
- else if (VT == MVT::i64)
- LC = (isSigned ? RTLIB::SDIV_I64 : RTLIB::UDIV_I64);
- else if (VT == MVT::i128)
- LC = (isSigned ? RTLIB::SDIV_I128 : RTLIB::UDIV_I128);
- break;
- case ISD::MUL:
- if (VT == MVT::i16)
- LC = RTLIB::MUL_I16;
- else if (VT == MVT::i32)
- LC = RTLIB::MUL_I32;
- else if (VT == MVT::i64)
- LC = RTLIB::MUL_I64;
- else if (VT == MVT::i128)
- LC = RTLIB::MUL_I128;
- break;
- default: break;
- }
- if (LC != RTLIB::UNKNOWN_LIBCALL) {
- Result = ExpandLibCall(LC, Node, isSigned);
- break;
- }
-
- assert(0 && "Cannot expand this binary operator!");
- break;
- }
- }
- break;
case ISD::FCOPYSIGN: // FCOPYSIGN does not require LHS/RHS to match type!
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS.
@@ -3487,6 +3295,111 @@
Results.push_back(ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64,
RTLIB::REM_F80, RTLIB::REM_PPCF128));
break;
+ case ISD::EHSELECTION: {
+ unsigned Reg = TLI.getExceptionSelectorRegister();
+ assert(Reg && "Can't expand to unknown register!");
+ Results.push_back(DAG.getCopyFromReg(Node->getOperand(1), dl, Reg,
+ Node->getValueType(0)));
+ Results.push_back(Results[0].getValue(1));
+ break;
+ }
+ case ISD::EXCEPTIONADDR: {
+ unsigned Reg = TLI.getExceptionAddressRegister();
+ assert(Reg && "Can't expand to unknown register!");
+ Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, Reg,
+ Node->getValueType(0)));
+ Results.push_back(Results[0].getValue(1));
+ break;
+ }
+ case ISD::SUB: {
+ MVT VT = Node->getValueType(0);
+ assert(TLI.isOperationLegalOrCustom(ISD::ADD, VT) &&
+ TLI.isOperationLegalOrCustom(ISD::XOR, VT) &&
+ "Don't know how to expand this subtraction!");
+ Tmp1 = DAG.getNode(ISD::XOR, dl, VT, Node->getOperand(1),
+ DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT));
+ Tmp1 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT));
+ Results.push_back(DAG.getNode(ISD::ADD, dl, VT, Node->getOperand(0), Tmp1));
+ break;
+ }
+ case ISD::UDIV:
+ case ISD::UREM: {
+ bool isRem = Node->getOpcode() == ISD::UREM;
+ MVT VT = Node->getValueType(0);
+ SDVTList VTs = DAG.getVTList(VT, VT);
+ if (TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT))
+ Tmp1 = DAG.getNode(ISD::UDIVREM, dl, VTs, Node->getOperand(0),
+ Node->getOperand(1)).getValue(isRem);
+ else if (isRem)
+ Tmp1 = ExpandIntLibCall(Node, false, RTLIB::UREM_I16, RTLIB::UREM_I32,
+ RTLIB::UREM_I64, RTLIB::UREM_I128);
+ else
+ Tmp1 = ExpandIntLibCall(Node, false, RTLIB::UDIV_I16, RTLIB::UDIV_I32,
+ RTLIB::UDIV_I64, RTLIB::UDIV_I128);
+ Results.push_back(Tmp1);
+ break;
+ }
+ case ISD::SDIV:
+ case ISD::SREM: {
+ bool isRem = Node->getOpcode() == ISD::SREM;
+ MVT VT = Node->getValueType(0);
+ SDVTList VTs = DAG.getVTList(VT, VT);
+ if (TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT))
+ Tmp1 = DAG.getNode(ISD::SDIVREM, dl, VTs, Node->getOperand(0),
+ Node->getOperand(1)).getValue(isRem);
+ else if (isRem)
+ Tmp1 = ExpandIntLibCall(Node, true, RTLIB::SREM_I16, RTLIB::SREM_I32,
+ RTLIB::SREM_I64, RTLIB::SREM_I128);
+ else
+ Tmp1 = ExpandIntLibCall(Node, true, RTLIB::SDIV_I16, RTLIB::SDIV_I32,
+ RTLIB::SDIV_I64, RTLIB::SDIV_I128);
+ Results.push_back(Tmp1);
+ break;
+ }
+ case ISD::MULHU:
+ case ISD::MULHS: {
+ unsigned ExpandOpcode = Node->getOpcode() == ISD::MULHU ? ISD::UMUL_LOHI :
+ ISD::SMUL_LOHI;
+ MVT VT = Node->getValueType(0);
+ SDVTList VTs = DAG.getVTList(VT, VT);
+ assert(TLI.isOperationLegalOrCustom(ExpandOpcode, VT) &&
+ "If this wasn't legal, it shouldn't have been created!");
+ Tmp1 = DAG.getNode(ExpandOpcode, dl, VTs, Node->getOperand(0),
+ Node->getOperand(1));
+ Results.push_back(Tmp1.getValue(1));
+ break;
+ }
+ case ISD::MUL: {
+ MVT VT = Node->getValueType(0);
+ SDVTList VTs = DAG.getVTList(VT, VT);
+ // See if multiply or divide can be lowered using two-result operations.
+ // We just need the low half of the multiply; try both the signed
+ // and unsigned forms. If the target supports both SMUL_LOHI and
+ // UMUL_LOHI, form a preference by checking which forms of plain
+ // MULH it supports.
+ bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT);
+ bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT);
+ bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT);
+ bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT);
+ unsigned OpToUse = 0;
+ if (HasSMUL_LOHI && !HasMULHS) {
+ OpToUse = ISD::SMUL_LOHI;
+ } else if (HasUMUL_LOHI && !HasMULHU) {
+ OpToUse = ISD::UMUL_LOHI;
+ } else if (HasSMUL_LOHI) {
+ OpToUse = ISD::SMUL_LOHI;
+ } else if (HasUMUL_LOHI) {
+ OpToUse = ISD::UMUL_LOHI;
+ }
+ if (OpToUse) {
+ Results.push_back(DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2));
+ break;
+ }
+ Tmp1 = ExpandIntLibCall(Node, false, RTLIB::MUL_I16, RTLIB::MUL_I32,
+ RTLIB::MUL_I64, RTLIB::MUL_I128);
+ Results.push_back(Tmp1);
+ break;
+ }
case ISD::GLOBAL_OFFSET_TABLE:
case ISD::GlobalAddress:
case ISD::GlobalTLSAddress:
More information about the llvm-commits
mailing list