X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FLegalizeDAG.cpp;h=688e4f9fea07c5fca399b751c8eaeea62f496b0d;hb=b027fa001f16660a231a54ecea6a79f5c7855d7c;hp=a2f4827870af23d4f9d070924cf42f58220023a8;hpb=6c9c6800b844771117943c400d0a9a47460a46b9;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index a2f4827870a..688e4f9fea0 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -15,6 +15,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetData.h" @@ -619,13 +620,13 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, SDOperand Ptr = LD->getBasePtr(); MVT::ValueType VT = LD->getValueType(0); MVT::ValueType LoadedVT = LD->getLoadedVT(); - if (MVT::isFloatingPoint(VT)) { + if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT)) { // Expand to a (misaligned) integer load of the same size, // then bitconvert to floating point. MVT::ValueType intVT; - if (LoadedVT==MVT::f64) + if (LoadedVT == MVT::f64) intVT = MVT::i64; - else if (LoadedVT==MVT::f32) + else if (LoadedVT == MVT::f32) intVT = MVT::i32; else assert(0 && "Unaligned load of unsupported floating point type"); @@ -641,11 +642,25 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other), Ops, 2); } - assert(MVT::isInteger(LoadedVT) && "Unaligned load of unsupported type."); - MVT::ValueType NewLoadedVT = LoadedVT - 1; - int NumBits = MVT::getSizeInBits(NewLoadedVT); - int Alignment = LD->getAlignment(); - int IncrementSize = NumBits / 8; + assert((MVT::isInteger(LoadedVT) || MVT::isVector(LoadedVT)) && + "Unaligned load of unsupported type."); + + // Compute the new VT that is half the size of the old one. We either have an + // integer MVT or we have a vector MVT. + unsigned NumBits = MVT::getSizeInBits(LoadedVT); + MVT::ValueType NewLoadedVT; + if (!MVT::isVector(LoadedVT)) { + NewLoadedVT = MVT::getIntegerType(NumBits/2); + } else { + // FIXME: This is not right for <1 x anything> it is also not right for + // non-power-of-two vectors. + NewLoadedVT = MVT::getVectorType(MVT::getVectorElementType(LoadedVT), + MVT::getVectorNumElements(LoadedVT)/2); + } + NumBits >>= 1; + + unsigned Alignment = LD->getAlignment(); + unsigned IncrementSize = NumBits / 8; ISD::LoadExtType HiExtType = LD->getExtensionType(); // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD. @@ -843,7 +858,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Expand: { unsigned Reg = TLI.getExceptionAddressRegister(); - Result = DAG.getCopyFromReg(Tmp1, Reg, VT).getValue(Op.ResNo); + Result = DAG.getCopyFromReg(Tmp1, Reg, VT); } break; case TargetLowering::Custom: @@ -853,12 +868,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Legal: { SDOperand Ops[] = { DAG.getConstant(0, VT), Tmp1 }; Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other), - Ops, 2).getValue(Op.ResNo); + Ops, 2); break; } } } - break; + if (Result.Val->getNumValues() == 1) break; + + assert(Result.Val->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.ResNo ? Tmp2 : Tmp1; case ISD::EHSELECTION: { Tmp1 = LegalizeOp(Node->getOperand(0)); Tmp2 = LegalizeOp(Node->getOperand(1)); @@ -867,7 +893,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Expand: { unsigned Reg = TLI.getExceptionSelectorRegister(); - Result = DAG.getCopyFromReg(Tmp2, Reg, VT).getValue(Op.ResNo); + Result = DAG.getCopyFromReg(Tmp2, Reg, VT); } break; case TargetLowering::Custom: @@ -877,12 +903,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Legal: { SDOperand Ops[] = { DAG.getConstant(0, VT), Tmp2 }; Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other), - Ops, 2).getValue(Op.ResNo); + Ops, 2); break; } } } - break; + if (Result.Val->getNumValues() == 1) break; + + assert(Result.Val->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.ResNo ? Tmp2 : Tmp1; case ISD::EH_RETURN: { MVT::ValueType VT = Node->getValueType(0); // The only "good" option for this node is to custom lower it. @@ -5173,10 +5210,21 @@ SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp, // Otherwise, try a larger type. } - // Okay, we found the operation and type to use. Truncate the result of the - // extended FP_TO_*INT operation to the desired size. - return DAG.getNode(ISD::TRUNCATE, DestVT, - DAG.getNode(OpToUse, NewOutTy, LegalOp)); + + // Okay, we found the operation and type to use. + SDOperand Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp); + + // If the operation produces an invalid type, it must be custom lowered. Use + // the target lowering hooks to expand it. Just keep the low part of the + // expanded operation, we know that we're truncating anyway. + if (getTypeAction(NewOutTy) == Expand) { + Operation = SDOperand(TLI.ExpandOperationResult(Operation.Val, DAG), 0); + assert(Operation.Val && "Didn't return anything"); + } + + // Truncate the result of the extended FP_TO_*INT operation to the desired + // size. + return DAG.getNode(ISD::TRUNCATE, DestVT, Operation); } /// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. @@ -5374,6 +5422,20 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Lo = Node->getOperand(0); Hi = Node->getOperand(1); break; + + case ISD::MERGE_VALUES: + if (Node->getNumValues() == 1) { + ExpandOp(Op.getOperand(0), Lo, Hi); + break; + } + // FIXME: For now only expand i64,chain = MERGE_VALUES (x, y) + assert(Op.ResNo == 0 && Node->getNumValues() == 2 && + Op.getValue(1).getValueType() == MVT::Other && + "unhandled MERGE_VALUES"); + ExpandOp(Op.getOperand(0), Lo, Hi); + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), LegalizeOp(Op.getOperand(1))); + break; case ISD::SIGN_EXTEND_INREG: ExpandOp(Node->getOperand(0), Lo, Hi); @@ -5638,16 +5700,17 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ break; } - case ISD::READCYCLECOUNTER: + case ISD::READCYCLECOUNTER: { assert(TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == TargetLowering::Custom && "Must custom expand ReadCycleCounter"); - Lo = TLI.LowerOperation(Op, DAG); - assert(Lo.Val && "Node must be custom expanded!"); - Hi = Lo.getValue(1); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + assert(Tmp.Val && "Node must be custom expanded!"); + ExpandOp(Tmp.getValue(0), Lo, Hi); AddLegalizedOperand(SDOperand(Node, 1), // Remember we legalized the chain. - LegalizeOp(Lo.getValue(2))); + LegalizeOp(Tmp.getValue(1))); break; + } // These operators cannot be expanded directly, emit them as calls to // library functions.