[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Jan 10 21:57:35 PST 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.19 -> 1.20
---
Log message:
Teach legalize to lower MEMSET/MEMCPY/MEMMOVE operations if the target
does not support them.
---
Diffs of the changes: (+52 -7)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.19 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.20
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.19 Mon Jan 10 15:02:37 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Jan 10 23:57:22 2005
@@ -15,6 +15,7 @@
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/Constants.h"
#include <iostream>
using namespace llvm;
@@ -221,13 +222,8 @@
}
}
- // If there is more than one use of this, see if we already legalized it.
- // There is no use remembering values that only have a single use, as the map
- // entries will never be reused.
- if (!Op.Val->hasOneUse()) {
- std::map<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
- if (I != LegalizedNodes.end()) return I->second;
- }
+ std::map<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
+ if (I != LegalizedNodes.end()) return I->second;
SDOperand Tmp1, Tmp2, Tmp3;
@@ -581,6 +577,55 @@
}
break;
+ case ISD::MEMSET:
+ case ISD::MEMCPY:
+ case ISD::MEMMOVE: {
+ Tmp1 = LegalizeOp(Node->getOperand(0));
+ Tmp2 = LegalizeOp(Node->getOperand(1));
+ Tmp3 = LegalizeOp(Node->getOperand(2));
+ SDOperand Tmp4 = LegalizeOp(Node->getOperand(3));
+ SDOperand Tmp5 = LegalizeOp(Node->getOperand(4));
+ if (TLI.isOperationSupported(Node->getOpcode(), MVT::Other)) {
+ if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
+ Tmp3 != Node->getOperand(2) || Tmp4 != Node->getOperand(3) ||
+ Tmp5 != Node->getOperand(4)) {
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Tmp1); Ops.push_back(Tmp2); Ops.push_back(Tmp3);
+ Ops.push_back(Tmp4); Ops.push_back(Tmp5);
+ Result = DAG.getNode(Node->getOpcode(), MVT::Other, Ops);
+ }
+ } else {
+ // Otherwise, the target does not support this operation. Lower the
+ // operation to an explicit libcall as appropriate.
+ MVT::ValueType IntPtr = TLI.getPointerTy();
+ const Type *IntPtrTy = TLI.getTargetData().getIntPtrType();
+ std::vector<std::pair<SDOperand, const Type*> > Args;
+
+ const char *FnName;
+ if (Node->getOpcode() == ISD::MEMSET) {
+ Args.push_back(std::make_pair(Tmp2, IntPtrTy));
+ // Extend the ubyte argument to be an int value for the call.
+ Tmp3 = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Tmp3);
+ Args.push_back(std::make_pair(Tmp3, Type::IntTy));
+ Args.push_back(std::make_pair(Tmp4, IntPtrTy));
+
+ FnName = "memset";
+ } else if (Node->getOpcode() == ISD::MEMCPY ||
+ Node->getOpcode() == ISD::MEMMOVE) {
+ Args.push_back(std::make_pair(Tmp2, IntPtrTy));
+ Args.push_back(std::make_pair(Tmp3, IntPtrTy));
+ Args.push_back(std::make_pair(Tmp4, IntPtrTy));
+ FnName = Node->getOpcode() == ISD::MEMMOVE ? "memmove" : "memcpy";
+ } else {
+ assert(0 && "Unknown op!");
+ }
+ std::pair<SDOperand,SDOperand> CallResult =
+ TLI.LowerCallTo(Tmp1, Type::VoidTy,
+ DAG.getExternalSymbol(FnName, IntPtr), Args, DAG);
+ Result = LegalizeOp(CallResult.second);
+ }
+ break;
+ }
case ISD::ADD:
case ISD::SUB:
case ISD::MUL:
More information about the llvm-commits
mailing list