Add support for promoting ADD/MUL.

Add support for new SIGN_EXTEND_INREG, ZERO_EXTEND_INREG, and FP_ROUND_INREG operators.
Realize that if we do any promotions, we need to iterate SelectionDAG
construction.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19569 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-01-15 06:18:18 +00:00
parent 859157daee
commit 0f69b29108

View File

@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Constants.h"
#include <iostream>
using namespace llvm;
@ -403,6 +404,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
return Result.getValue(Op.ResNo);
case ISD::EXTLOAD:
case ISD::SEXTLOAD:
case ISD::ZEXTLOAD:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
if (Tmp1 != Node->getOperand(0) ||
Tmp2 != Node->getOperand(1))
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, Tmp2,
cast<MVTSDNode>(Node)->getExtraValueType());
else
Result = SDOperand(Node, 0);
// Since loads produce two values, make sure to remember that we legalized
// both of them.
AddLegalizedOperand(SDOperand(Node, 0), Result);
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
return Result.getValue(Op.ResNo);
case ISD::EXTRACT_ELEMENT:
// Get both the low and high parts.
ExpandOp(Node->getOperand(0), Tmp1, Tmp2);
@ -546,6 +565,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
Result = DAG.getNode(ISD::STORE, MVT::Other, Result, Hi, Tmp2);
}
break;
case ISD::TRUNCSTORE:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the pointer.
switch (getTypeAction(Node->getOperand(1).getValueType())) {
case Legal:
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,
cast<MVTSDNode>(Node)->getExtraValueType());
break;
case Promote:
case Expand:
assert(0 && "Cannot handle illegal TRUNCSTORE yet!");
}
break;
case ISD::SELECT:
// FIXME: BOOLS MAY REQUIRE PROMOTION!
Tmp1 = LegalizeOp(Node->getOperand(0)); // Cond
@ -736,6 +772,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
}
}
break;
case ISD::FP_ROUND_INREG:
case ISD::SIGN_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());
break;
}
if (!Op.Val->hasOneUse())
@ -760,6 +804,11 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
SDOperand Result;
SDNode *Node = Op.Val;
// Promotion needs an optimization step to clean up after it, and is not
// careful to avoid operations the target does not support. Make sure that
// all generated operations are legalized in the next iteration.
NeedsAnotherIteration = true;
switch (Node->getOpcode()) {
default:
std::cerr << "NODE: "; Node->dump(); std::cerr << "\n";
@ -800,6 +849,23 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
break;
case ISD::ADD:
case ISD::MUL:
// The input may have strange things in the top bits of the registers, but
// these operations don't care. They may have wierd bits going out, but
// that too is okay if they are integer operations.
Tmp1 = PromoteOp(Node->getOperand(0));
Tmp2 = PromoteOp(Node->getOperand(1));
assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
// However, if this is a floating point operation, they will give excess
// precision that we may not be able to tolerate. If we DO allow excess
// precision, just leave it, otherwise excise it.
if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision)
Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
break;
case ISD::LOAD:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.