diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2007-10-19 10:41:11 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2007-10-19 10:41:11 +0000 |
commit | 5c0d6ed325417baa5d119af9c2b6790231d8565f (patch) | |
tree | 38d15c900b43ca45f2eda6aadb5c330c664ca19e /lib/CodeGen/SelectionDAG | |
parent | 1f39dc42cdb70b5ebe86e3076c025a814adcbc41 (diff) |
Add support for byval function whose argument is not 32 bit aligned.
To do this it is necessary to add a "always inline" argument to the
memcpy node. For completeness I have also added this node to memmove
and memset. I have also added getMem* functions, because the extra
argument makes it cumbersome to use getNode and because I get confused
by it :-)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43172 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 24 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 17 |
3 files changed, 55 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 9516dff6cb..1ad8e80258 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2506,18 +2506,31 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { break; } + SDOperand Tmp6; + switch (getTypeAction(Node->getOperand(5).getValueType())) { // bool + case Expand: assert(0 && "Cannot expand this yet!"); + case Legal: + Tmp6 = LegalizeOp(Node->getOperand(5)); + break; + case Promote: + Tmp6 = PromoteOp(Node->getOperand(5)); + break; + } + switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) { default: assert(0 && "This action not implemented for this operation!"); case TargetLowering::Custom: isCustom = true; // FALLTHROUGH - case TargetLowering::Legal: - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5); + case TargetLowering::Legal: { + SDOperand Ops[] = { Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6 }; + Result = DAG.UpdateNodeOperands(Result, Ops, 6); if (isCustom) { Tmp1 = TLI.LowerOperation(Result, DAG); if (Tmp1.Val) Result = Tmp1; } break; + } case TargetLowering::Expand: { // Otherwise, the target does not support this operation. Lower the // operation to an explicit libcall as appropriate. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e6ce2eb995..09e8b579a0 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2269,6 +2269,30 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, return getNode(Opcode, VT, Ops, 5); } +SDOperand SelectionDAG::getMemcpy(SDOperand Chain, SDOperand Dest, + SDOperand Src, SDOperand Size, + SDOperand Align, + SDOperand AlwaysInline) { + SDOperand Ops[] = { Chain, Dest, Src, Size, Align, AlwaysInline }; + return getNode(ISD::MEMCPY, MVT::Other, Ops, 6); +} + +SDOperand SelectionDAG::getMemmove(SDOperand Chain, SDOperand Dest, + SDOperand Src, SDOperand Size, + SDOperand Align, + SDOperand AlwaysInline) { + SDOperand Ops[] = { Chain, Dest, Src, Size, Align, AlwaysInline }; + return getNode(ISD::MEMMOVE, MVT::Other, Ops, 6); +} + +SDOperand SelectionDAG::getMemset(SDOperand Chain, SDOperand Dest, + SDOperand Src, SDOperand Size, + SDOperand Align, + SDOperand AlwaysInline) { + SDOperand Ops[] = { Chain, Dest, Src, Size, Align, AlwaysInline }; + return getNode(ISD::MEMSET, MVT::Other, Ops, 6); +} + SDOperand SelectionDAG::getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, const Value *SV, int SVOffset, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index a5b6300f6e..f69b095940 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -4367,7 +4367,22 @@ void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { } } - DAG.setRoot(DAG.getNode(Op, MVT::Other, getRoot(), Op1, Op2, Op3, Op4)); + SDOperand AlwaysInline = DAG.getConstant(0, MVT::i1); + SDOperand Node; + switch(Op) { + default: + assert(0 && "Unknown Op"); + case ISD::MEMCPY: + Node = DAG.getMemcpy(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline); + break; + case ISD::MEMMOVE: + Node = DAG.getMemmove(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline); + break; + case ISD::MEMSET: + Node = DAG.getMemset(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline); + break; + } + DAG.setRoot(Node); } //===----------------------------------------------------------------------===// |