[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Jan 14 23:15:31 PST 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.29 -> 1.30
---
Log message:
Add support for legalizing FP_ROUND_INREG, SIGN_EXTEND_INREG, and
ZERO_EXTEND_INREG for targets that don't support them.
---
Diffs of the changes: (+58 -21)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.29 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.30
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.29 Sat Jan 15 00:18:18 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Jan 15 01:15:18 2005
@@ -14,6 +14,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetOptions.h"
@@ -21,20 +22,6 @@
#include <iostream>
using namespace llvm;
-static const Type *getTypeFor(MVT::ValueType VT) {
- switch (VT) {
- default: assert(0 && "Unknown MVT!");
- case MVT::i1: return Type::BoolTy;
- case MVT::i8: return Type::UByteTy;
- case MVT::i16: return Type::UShortTy;
- case MVT::i32: return Type::UIntTy;
- case MVT::i64: return Type::ULongTy;
- case MVT::f32: return Type::FloatTy;
- case MVT::f64: return Type::DoubleTy;
- }
-}
-
-
//===----------------------------------------------------------------------===//
/// SelectionDAGLegalize - This takes an arbitrary SelectionDAG as input and
/// hacks on it until the target machine can handle it. This involves
@@ -574,7 +561,7 @@
Tmp2 = LegalizeOp(Node->getOperand(1));
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
Tmp3 != Node->getOperand(2))
- Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp3, Tmp2,
+ Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3,
cast<MVTSDNode>(Node)->getExtraValueType());
break;
case Promote:
@@ -774,13 +761,63 @@
break;
case ISD::FP_ROUND_INREG:
case ISD::SIGN_EXTEND_INREG:
- case ISD::ZERO_EXTEND_INREG:
+ case ISD::ZERO_EXTEND_INREG: {
Tmp1 = LegalizeOp(Node->getOperand(0));
- if (Tmp1 != Node->getOperand(0))
- Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,
- cast<MVTSDNode>(Node)->getExtraValueType());
+ MVT::ValueType ExtraVT = cast<MVTSDNode>(Node)->getExtraValueType();
+
+ // If this operation is not supported, convert it to a shl/shr or load/store
+ // pair.
+ if (!TLI.isOperationSupported(Node->getOpcode(), ExtraVT)) {
+ // If this is an integer extend and shifts are supported, do that.
+ if (Node->getOpcode() == ISD::ZERO_EXTEND_INREG) {
+ // NOTE: we could fall back on load/store here too for targets without
+ // AND. However, it is doubtful that any exist.
+ // AND out the appropriate bits.
+ SDOperand Mask =
+ DAG.getConstant((1ULL << MVT::getSizeInBits(ExtraVT))-1,
+ Node->getValueType(0));
+ Result = DAG.getNode(ISD::AND, Node->getValueType(0),
+ Node->getOperand(0), Mask);
+ } else if (Node->getOpcode() == ISD::SIGN_EXTEND_INREG) {
+ // NOTE: we could fall back on load/store here too for targets without
+ // SAR. However, it is doubtful that any exist.
+ unsigned BitsDiff = MVT::getSizeInBits(Node->getValueType(0)) -
+ MVT::getSizeInBits(ExtraVT);
+ SDOperand ShiftCst = DAG.getConstant(BitsDiff, MVT::i8);
+ Result = DAG.getNode(ISD::SHL, Node->getValueType(0),
+ Node->getOperand(0), ShiftCst);
+ Result = DAG.getNode(ISD::SRA, Node->getValueType(0),
+ Result, ShiftCst);
+ } else if (Node->getOpcode() == ISD::FP_ROUND_INREG) {
+ // The only way we can lower this is to turn it into a STORETRUNC,
+ // EXTLOAD pair, targetting a temporary location (a stack slot).
+
+ // NOTE: there is a choice here between constantly creating new stack
+ // slots and always reusing the same one. We currently always create
+ // new ones, as reuse may inhibit scheduling.
+ const Type *Ty = MVT::getTypeForValueType(ExtraVT);
+ unsigned TySize = (unsigned)TLI.getTargetData().getTypeSize(Ty);
+ unsigned Align = TLI.getTargetData().getTypeAlignment(Ty);
+ MachineFunction &MF = DAG.getMachineFunction();
+ int SSFI =
+ MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align);
+ SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
+ Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, DAG.getEntryNode(),
+ Node->getOperand(0), StackSlot, ExtraVT);
+ Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0),
+ Result, StackSlot, ExtraVT);
+ } else {
+ assert(0 && "Unknown op");
+ }
+ Result = LegalizeOp(Result);
+ } else {
+ if (Tmp1 != Node->getOperand(0))
+ Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,
+ ExtraVT);
+ }
break;
}
+ }
if (!Op.Val->hasOneUse())
AddLegalizedOperand(Op, Result);
@@ -1057,14 +1094,14 @@
TargetLowering::ArgListTy Args;
for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
Args.push_back(std::make_pair(Node->getOperand(i),
- getTypeFor(Node->getOperand(i).getValueType())));
+ MVT::getTypeForValueType(Node->getOperand(i).getValueType())));
SDOperand Callee = DAG.getExternalSymbol(LibCallName, TLI.getPointerTy());
// We don't care about token chains for libcalls. We just use the entry
// node as our input and ignore the output chain. This allows us to place
// calls wherever we need them to satisfy data dependences.
SDOperand Result = TLI.LowerCallTo(DAG.getEntryNode(),
- getTypeFor(Op.getValueType()), Callee,
+ MVT::getTypeForValueType(Op.getValueType()), Callee,
Args, DAG).first;
ExpandOp(Result, Lo, Hi);
}
More information about the llvm-commits
mailing list