aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2007-10-19 10:41:11 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2007-10-19 10:41:11 +0000
commit5c0d6ed325417baa5d119af9c2b6790231d8565f (patch)
tree38d15c900b43ca45f2eda6aadb5c330c664ca19e /lib/CodeGen/SelectionDAG
parent1f39dc42cdb70b5ebe86e3076c025a814adcbc41 (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.cpp17
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp24
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp17
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);
}
//===----------------------------------------------------------------------===//