mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-03 09:21:02 +00:00
Reapply 91904.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91996 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7fb0ead091
commit
76d2f9a4db
@ -36,7 +36,10 @@ class VISIBILITY_HIDDEN PIC16DAGToDAGISel : public SelectionDAGISel {
|
|||||||
public:
|
public:
|
||||||
explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) :
|
explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) :
|
||||||
SelectionDAGISel(tm),
|
SelectionDAGISel(tm),
|
||||||
TM(tm), PIC16Lowering(*TM.getTargetLowering()) {}
|
TM(tm), PIC16Lowering(*TM.getTargetLowering()) {
|
||||||
|
// Keep PIC16 specific DAGISel to use during the lowering
|
||||||
|
PIC16Lowering.ISel = this;
|
||||||
|
}
|
||||||
|
|
||||||
// Pass Name
|
// Pass Name
|
||||||
virtual const char *getPassName() const {
|
virtual const char *getPassName() const {
|
||||||
|
@ -1482,7 +1482,8 @@ bool PIC16TargetLowering::isDirectLoad(const SDValue Op) {
|
|||||||
// operand no. of the operand to be converted in 'MemOp'. Remember, PIC16 has
|
// operand no. of the operand to be converted in 'MemOp'. Remember, PIC16 has
|
||||||
// no instruction that can operation on two registers. Most insns take
|
// no instruction that can operation on two registers. Most insns take
|
||||||
// one register and one memory operand (addwf) / Constant (addlw).
|
// one register and one memory operand (addwf) / Constant (addlw).
|
||||||
bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp) {
|
bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp,
|
||||||
|
SelectionDAG &DAG) {
|
||||||
// If one of the operand is a constant, return false.
|
// If one of the operand is a constant, return false.
|
||||||
if (Op.getOperand(0).getOpcode() == ISD::Constant ||
|
if (Op.getOperand(0).getOpcode() == ISD::Constant ||
|
||||||
Op.getOperand(1).getOpcode() == ISD::Constant)
|
Op.getOperand(1).getOpcode() == ISD::Constant)
|
||||||
@ -1491,11 +1492,33 @@ bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp) {
|
|||||||
// Return false if one of the operands is already a direct
|
// Return false if one of the operands is already a direct
|
||||||
// load and that operand has only one use.
|
// load and that operand has only one use.
|
||||||
if (isDirectLoad(Op.getOperand(0))) {
|
if (isDirectLoad(Op.getOperand(0))) {
|
||||||
if (Op.getOperand(0).hasOneUse())
|
if (Op.getOperand(0).hasOneUse()) {
|
||||||
return false;
|
// Legal and profitable folding check uses the NodeId of DAG nodes.
|
||||||
else
|
// This NodeId is assigned by topological order. Therefore first
|
||||||
MemOp = 0;
|
// assign topological order then perform legal and profitable check.
|
||||||
|
// Note:- Though this ordering is done before begining with legalization,
|
||||||
|
// newly added node during legalization process have NodeId=-1 (NewNode)
|
||||||
|
// therefore before performing any check proper ordering of the node is
|
||||||
|
// required.
|
||||||
|
DAG.AssignTopologicalOrder();
|
||||||
|
|
||||||
|
// Direct load operands are folded in binary operations. But before folding
|
||||||
|
// verify if this folding is legal. Fold only if it is legal otherwise
|
||||||
|
// convert this direct load to a separate memory operation.
|
||||||
|
if(ISel->IsLegalAndProfitableToFold(Op.getOperand(0).getNode(),
|
||||||
|
Op.getNode(), Op.getNode()))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
MemOp = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For operations that are non-cummutative there is no need to check
|
||||||
|
// for right operand because folding right operand may result in
|
||||||
|
// incorrect operation.
|
||||||
|
if (! SelectionDAG::isCommutativeBinOp(Op.getOpcode()))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (isDirectLoad(Op.getOperand(1))) {
|
if (isDirectLoad(Op.getOperand(1))) {
|
||||||
if (Op.getOperand(1).hasOneUse())
|
if (Op.getOperand(1).hasOneUse())
|
||||||
return false;
|
return false;
|
||||||
@ -1514,7 +1537,7 @@ SDValue PIC16TargetLowering::LowerBinOp(SDValue Op, SelectionDAG &DAG) {
|
|||||||
assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
|
assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
|
||||||
|
|
||||||
unsigned MemOp = 1;
|
unsigned MemOp = 1;
|
||||||
if (NeedToConvertToMemOp(Op, MemOp)) {
|
if (NeedToConvertToMemOp(Op, MemOp, DAG)) {
|
||||||
// Put one value on stack.
|
// Put one value on stack.
|
||||||
SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl);
|
SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl);
|
||||||
|
|
||||||
@ -1533,7 +1556,7 @@ SDValue PIC16TargetLowering::LowerADD(SDValue Op, SelectionDAG &DAG) {
|
|||||||
assert (Op.getValueType() == MVT::i8 && "illegal add to lower");
|
assert (Op.getValueType() == MVT::i8 && "illegal add to lower");
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
unsigned MemOp = 1;
|
unsigned MemOp = 1;
|
||||||
if (NeedToConvertToMemOp(Op, MemOp)) {
|
if (NeedToConvertToMemOp(Op, MemOp, DAG)) {
|
||||||
// Put one value on stack.
|
// Put one value on stack.
|
||||||
SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl);
|
SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl);
|
||||||
|
|
||||||
@ -1574,7 +1597,7 @@ SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
|
|||||||
DAG.getConstant(0-(C->getZExtValue()), MVT::i8));
|
DAG.getConstant(0-(C->getZExtValue()), MVT::i8));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NeedToConvertToMemOp(Op, MemOp) ||
|
if (NeedToConvertToMemOp(Op, MemOp, DAG) ||
|
||||||
(isDirectLoad(Op.getOperand(1)) &&
|
(isDirectLoad(Op.getOperand(1)) &&
|
||||||
(!isDirectLoad(Op.getOperand(0))) &&
|
(!isDirectLoad(Op.getOperand(0))) &&
|
||||||
(Op.getOperand(0).getOpcode() != ISD::Constant)))
|
(Op.getOperand(0).getOpcode() != ISD::Constant)))
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "PIC16.h"
|
#include "PIC16.h"
|
||||||
#include "PIC16Subtarget.h"
|
#include "PIC16Subtarget.h"
|
||||||
#include "llvm/CodeGen/SelectionDAG.h"
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
|
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -216,7 +217,9 @@ namespace llvm {
|
|||||||
|
|
||||||
// This function checks if we need to put an operand of an operation on
|
// This function checks if we need to put an operand of an operation on
|
||||||
// stack and generate a load or not.
|
// stack and generate a load or not.
|
||||||
bool NeedToConvertToMemOp(SDValue Op, unsigned &MemOp);
|
// DAG parameter is required to access DAG information during
|
||||||
|
// analysis.
|
||||||
|
bool NeedToConvertToMemOp(SDValue Op, unsigned &MemOp, SelectionDAG &DAG);
|
||||||
|
|
||||||
/// Subtarget - Keep a pointer to the PIC16Subtarget around so that we can
|
/// Subtarget - Keep a pointer to the PIC16Subtarget around so that we can
|
||||||
/// make the right decision when generating code for different targets.
|
/// make the right decision when generating code for different targets.
|
||||||
@ -239,6 +242,11 @@ namespace llvm {
|
|||||||
// Check if operation has a direct load operand.
|
// Check if operation has a direct load operand.
|
||||||
inline bool isDirectLoad(const SDValue Op);
|
inline bool isDirectLoad(const SDValue Op);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Keep a pointer to SelectionDAGISel to access its public
|
||||||
|
// interface (It is required during legalization)
|
||||||
|
SelectionDAGISel *ISel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The frameindexes generated for spill/reload are stack based.
|
// The frameindexes generated for spill/reload are stack based.
|
||||||
// This maps maintain zero based indexes for these FIs.
|
// This maps maintain zero based indexes for these FIs.
|
||||||
|
15
test/CodeGen/PIC16/C16-49.ll
Normal file
15
test/CodeGen/PIC16/C16-49.ll
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
;RUN: llvm-as < %s | llc -march=pic16
|
||||||
|
|
||||||
|
@aa = global i16 55, align 1 ; <i16*> [#uses=1]
|
||||||
|
@bb = global i16 44, align 1 ; <i16*> [#uses=1]
|
||||||
|
@PORTD = external global i8 ; <i8*> [#uses=1]
|
||||||
|
|
||||||
|
define void @foo() nounwind {
|
||||||
|
entry:
|
||||||
|
%tmp = volatile load i16* @aa ; <i16> [#uses=1]
|
||||||
|
%tmp1 = volatile load i16* @bb ; <i16> [#uses=1]
|
||||||
|
%sub = sub i16 %tmp, %tmp1 ; <i16> [#uses=1]
|
||||||
|
%conv = trunc i16 %sub to i8 ; <i8> [#uses=1]
|
||||||
|
store i8 %conv, i8* @PORTD
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user