Remove trailing whitespace

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21425 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Misha Brukman
2005-04-21 23:30:14 +00:00
parent 4633f1cde8
commit b5f662fa03
133 changed files with 3142 additions and 3142 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- PowerPC.h - Top-level interface for PowerPC representation -*- C++ -*-//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the entry points for global functions defined in the LLVM
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,10 +1,10 @@
//===- PPC32JITInfo.h - PowerPC/Darwin JIT interface --------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetJITInfo class.
+3 -3
View File
@@ -1,12 +1,12 @@
//===-- PPC64CodeEmitter.cpp - JIT Code Emitter for PPC64 -----*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
+95 -95
View File
@@ -4,7 +4,7 @@
//
// This file was developed by Nate Begeman and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file defines a pattern matching instruction selector for 64 bit PowerPC.
@@ -45,7 +45,7 @@ namespace {
addRegisterClass(MVT::i64, PPC64::GPRCRegisterClass);
addRegisterClass(MVT::f32, PPC64::FPRCRegisterClass);
addRegisterClass(MVT::f64, PPC64::FPRCRegisterClass);
// PowerPC has no intrinsics for these particular operations
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
@@ -62,7 +62,7 @@ namespace {
setShiftAmountFlavor(Extend); // shl X, 32 == 0
addLegalFPImmediate(+0.0); // Necessary for FSEL
addLegalFPImmediate(-0.0); //
addLegalFPImmediate(-0.0); //
computeRegisterProperties();
}
@@ -71,16 +71,16 @@ namespace {
/// lower the arguments for the specified function, into the specified DAG.
virtual std::vector<SDOperand>
LowerArguments(Function &F, SelectionDAG &DAG);
/// LowerCallTo - This hook lowers an abstract call to a function into an
/// actual call.
virtual std::pair<SDOperand, SDOperand>
LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand>
LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
virtual std::pair<SDOperand,SDOperand>
LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
const Type *ArgTy, SelectionDAG &DAG);
@@ -101,8 +101,8 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineBasicBlock& BB = MF.front();
std::vector<SDOperand> ArgValues;
// Due to the rather complicated nature of the PowerPC ABI, rather than a
// Due to the rather complicated nature of the PowerPC ABI, rather than a
// fixed size array of physical args, for the sake of simplicity let the STL
// handle tracking them for us.
std::vector<unsigned> argVR, argPR, argOp;
@@ -110,7 +110,7 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
unsigned GPR_remaining = 8;
unsigned FPR_remaining = 13;
unsigned GPR_idx = 0, FPR_idx = 0;
static const unsigned GPR[] = {
static const unsigned GPR[] = {
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
};
@@ -126,13 +126,13 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
SDOperand newroot, argt;
bool needsLoad = false;
MVT::ValueType ObjectVT = getValueType(I->getType());
switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!");
case MVT::i1:
case MVT::i8:
case MVT::i16:
case MVT::i32:
case MVT::i32:
case MVT::i64:
if (GPR_remaining > 0) {
BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
@@ -148,7 +148,7 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
case MVT::f64:
if (FPR_remaining > 0) {
BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]);
argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT,
argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT,
DAG.getRoot());
--FPR_remaining;
++FPR_idx;
@@ -157,9 +157,9 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
}
break;
}
// We need to load the argument to a virtual register if we determined above
// that we ran out of physical registers of the appropriate type
// that we ran out of physical registers of the appropriate type
if (needsLoad) {
unsigned SubregOffset = 0;
switch (ObjectVT) {
@@ -167,18 +167,18 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
case MVT::i1:
case MVT::i8: SubregOffset = 7; break;
case MVT::i16: SubregOffset = 6; break;
case MVT::i32:
case MVT::i32:
case MVT::f32: SubregOffset = 4; break;
case MVT::i64:
case MVT::i64:
case MVT::f64: SubregOffset = 0; break;
}
int FI = MFI->CreateFixedObject(8, ArgOffset);
SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
FIN = DAG.getNode(ISD::ADD, MVT::i64, FIN,
FIN = DAG.getNode(ISD::ADD, MVT::i64, FIN,
DAG.getConstant(SubregOffset, MVT::i64));
argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN);
}
// Every 4 bytes of argument space consumes one of the GPRs available for
// argument passing.
if (GPR_remaining > 0) {
@@ -186,7 +186,7 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
++GPR_idx;
}
ArgOffset += 8;
DAG.setRoot(newroot.getValue(1));
ArgValues.push_back(argt);
}
@@ -203,7 +203,7 @@ PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i64, DAG.getRoot());
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
Val, FIN);
MemOps.push_back(Store);
// Increment the address by eight for the next argument to store
@@ -233,8 +233,8 @@ PPC64TargetLowering::LowerCallTo(SDOperand Chain,
DAG.getConstant(NumBytes, getPointerTy()));
} else {
NumBytes = 8 * Args.size(); // All arguments are rounded up to 8 bytes
// Just to be safe, we'll always reserve the full 48 bytes of linkage area
// Just to be safe, we'll always reserve the full 48 bytes of linkage area
// plus 64 bytes of argument space in case any called code gets funky on us.
if (NumBytes < 112) NumBytes = 112;
@@ -248,7 +248,7 @@ PPC64TargetLowering::LowerCallTo(SDOperand Chain,
// passing.
SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32,
DAG.getEntryNode());
// Figure out which arguments are going to go in registers, and which in
// memory. Also, if this is a vararg function, floating point operations
// must be stored to our stack, and loaded into integer regs as well, if
@@ -256,7 +256,7 @@ PPC64TargetLowering::LowerCallTo(SDOperand Chain,
unsigned ArgOffset = 48;
unsigned GPR_remaining = 8;
unsigned FPR_remaining = 13;
std::vector<SDOperand> MemOps;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
// PtrOff will be used to store the current argument to the stack if a
@@ -264,7 +264,7 @@ PPC64TargetLowering::LowerCallTo(SDOperand Chain,
SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
MVT::ValueType ArgVT = getValueType(Args[i].second);
switch (ArgVT) {
default: assert(0 && "Unexpected ValueType for argument!");
case MVT::i1:
@@ -323,14 +323,14 @@ PPC64TargetLowering::LowerCallTo(SDOperand Chain,
if (!MemOps.empty())
Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
}
std::vector<MVT::ValueType> RetVals;
MVT::ValueType RetTyVT = getValueType(RetTy);
if (RetTyVT != MVT::isVoid)
RetVals.push_back(RetTyVT);
RetVals.push_back(MVT::Other);
SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
Chain, Callee, args_to_use), 0);
Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
@@ -357,7 +357,7 @@ LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
}
return std::make_pair(Result, Chain);
}
std::pair<SDOperand, SDOperand> PPC64TargetLowering::
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
@@ -374,10 +374,10 @@ Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
/// SelectionDAG operations.
//===--------------------------------------------------------------------===//
class ISel : public SelectionDAGISel {
/// Comment Here.
PPC64TargetLowering PPC64Lowering;
/// ExprMap - As shared expressions are codegen'd, we keep track of which
/// vreg the value is produced in, so we only emit one copy of each compiled
/// tree.
@@ -385,37 +385,37 @@ class ISel : public SelectionDAGISel {
unsigned GlobalBaseReg;
bool GlobalBaseInitialized;
public:
ISel(TargetMachine &TM) : SelectionDAGISel(PPC64Lowering), PPC64Lowering(TM)
ISel(TargetMachine &TM) : SelectionDAGISel(PPC64Lowering), PPC64Lowering(TM)
{}
/// runOnFunction - Override this function in order to reset our per-function
/// variables.
virtual bool runOnFunction(Function &Fn) {
// Make sure we re-emit a set of the global base reg if necessary
GlobalBaseInitialized = false;
return SelectionDAGISel::runOnFunction(Fn);
}
}
/// InstructionSelectBasicBlock - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
DEBUG(BB->dump());
// Codegen the basic block.
Select(DAG.getRoot());
// Clear state used for selection.
ExprMap.clear();
}
unsigned getGlobalBaseReg();
unsigned getConstDouble(double floatVal, unsigned Result);
unsigned SelectSetCR0(SDOperand CC);
unsigned SelectExpr(SDOperand N);
unsigned SelectExprFP(SDOperand N, unsigned Result);
void Select(SDOperand N);
bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
void SelectBranchCC(SDOperand N);
};
@@ -435,7 +435,7 @@ static unsigned ExactLog2(unsigned Val) {
/// getImmediateForOpcode - This method returns a value indicating whether
/// the ConstantSDNode N can be used as an immediate to Opcode. The return
/// values are either 0, 1 or 2. 0 indicates that either N is not a
/// ConstantSDNode, or is not suitable for use by that opcode. A return value
/// ConstantSDNode, or is not suitable for use by that opcode. A return value
/// of 1 indicates that the constant may be used in normal immediate form. A
/// return value of 2 indicates that the constant may be used in shifted
/// immediate form. A return value of 3 indicates that log base 2 of the
@@ -446,7 +446,7 @@ static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
if (N.getOpcode() != ISD::Constant) return 0;
int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
switch(Opcode) {
default: return 0;
case ISD::ADD:
@@ -528,7 +528,7 @@ unsigned ISel::getGlobalBaseReg() {
return GlobalBaseReg;
}
/// getConstDouble - Loads a floating point value into a register, via the
/// getConstDouble - Loads a floating point value into a register, via the
/// Constant Pool. Optionally takes a register in which to load the value.
unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) {
unsigned Tmp1 = MakeReg(MVT::i64);
@@ -544,9 +544,9 @@ unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) {
unsigned ISel::SelectSetCR0(SDOperand CC) {
unsigned Opc, Tmp1, Tmp2;
static const unsigned CompareOpcodes[] =
static const unsigned CompareOpcodes[] =
{ PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW };
// If the first operand to the select is a SETCC node, then we can fold it
// into the branch that selects which value to return.
SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
@@ -557,7 +557,7 @@ unsigned ISel::SelectSetCR0(SDOperand CC) {
// Pass the optional argument U to getImmediateForOpcode for SETCC,
// so that it knows whether the SETCC immediate range is signed or not.
if (1 == getImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC,
if (1 == getImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC,
Tmp2, U)) {
if (U)
BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(Tmp2);
@@ -586,7 +586,7 @@ bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) {
offset = imm;
return false;
}
}
offset = SelectExpr(N.getOperand(1));
return true;
}
@@ -598,14 +598,14 @@ bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
void ISel::SelectBranchCC(SDOperand N)
{
assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
MachineBasicBlock *Dest =
MachineBasicBlock *Dest =
cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
// Get the MBB we will fall through to so that we can hand it off to the
// branch selection pass as an argument to the PPC::COND_BRANCH pseudo op.
//ilist<MachineBasicBlock>::iterator It = BB;
//MachineBasicBlock *Fallthrough = ++It;
Select(N.getOperand(0)); //chain
unsigned Opc = SelectSetCR0(N.getOperand(1));
// FIXME: Use this once we have something approximating two-way branches
@@ -645,7 +645,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE
unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1));
if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) {
switch(SetCC->getCondition()) {
@@ -704,12 +704,12 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
assert(0 && "Should never get here");
return 0;
}
unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
Opc = SelectSetCR0(N.getOperand(0));
// Create an iterator with which to insert the MBB for copying the false
// Create an iterator with which to insert the MBB for copying the false
// value and the MBB to hold the PHI instruction for this SetCC.
MachineBasicBlock *thisMBB = BB;
const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -749,7 +749,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
}
case ISD::FNEG:
if (!NoExcessFPPrecision &&
if (!NoExcessFPPrecision &&
ISD::ADD == N.getOperand(0).getOpcode() &&
N.getOperand(0).Val->hasOneUse() &&
ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
@@ -760,7 +760,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
} else if (!NoExcessFPPrecision &&
} else if (!NoExcessFPPrecision &&
ISD::SUB == N.getOperand(0).getOpcode() &&
N.getOperand(0).Val->hasOneUse() &&
ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
@@ -779,23 +779,23 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
}
return Result;
case ISD::FABS:
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
return Result;
case ISD::FP_ROUND:
assert (DestType == MVT::f32 &&
N.getOperand(0).getValueType() == MVT::f64 &&
assert (DestType == MVT::f32 &&
N.getOperand(0).getValueType() == MVT::f64 &&
"only f64 to f32 conversion supported here");
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1);
return Result;
case ISD::FP_EXTEND:
assert (DestType == MVT::f64 &&
N.getOperand(0).getValueType() == MVT::f32 &&
assert (DestType == MVT::f64 &&
N.getOperand(0).getValueType() == MVT::f32 &&
"only f32 to f64 conversion supported here");
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
@@ -807,13 +807,13 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
return Result;
case ISD::ConstantFP: {
ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
Result = getConstDouble(CN->getValue(), Result);
return Result;
}
case ISD::ADD:
if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
N.getOperand(0).Val->hasOneUse()) {
@@ -866,10 +866,10 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into
Tmp3 = MakeReg(MVT::i64); // temp reg to hold the conversion constant
unsigned ConstF = MakeReg(MVT::f64); // temp reg to hold the fp constant
int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
MachineConstantPool *CP = BB->getParent()->getConstantPool();
// FIXME: pull this FP constant generation stuff out into something like
// the simple ISel's getReg.
if (IsUnsigned) {
@@ -935,7 +935,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
if (ISD::CopyFromReg == opcode)
DestType = N.getValue(0).getValueType();
if (DestType == MVT::f64 || DestType == MVT::f32)
if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && ISD::UNDEF != opcode)
return SelectExprFP(N, Result);
@@ -983,7 +983,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
addFrameReference(BuildMI(BB, PPC::ADDI, 2, Result), (int)Tmp1, 0, false);
return Result;
case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
Tmp1 = MakeReg(MVT::i64);
@@ -1004,7 +1004,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ?
Node->getValueType(0) : cast<MVTSDNode>(Node)->getExtraValueType();
bool sext = (ISD::SEXTLOAD == opcode);
// Make sure we generate both values.
if (Result != 1)
ExprMap[N.getValue(1)] = 1; // Generate the token
@@ -1025,7 +1025,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
case MVT::f32: Opc = PPC::LFS; break;
case MVT::f64: Opc = PPC::LFD; break;
}
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
Tmp1 = MakeReg(MVT::i64);
int CPI = CP->getIndex();
@@ -1048,10 +1048,10 @@ unsigned ISel::SelectExpr(SDOperand N) {
}
return Result;
}
case ISD::CALL: {
unsigned GPR_idx = 0, FPR_idx = 0;
static const unsigned GPR[] = {
static const unsigned GPR[] = {
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
};
@@ -1066,13 +1066,13 @@ unsigned ISel::SelectExpr(SDOperand N) {
MachineInstr *CallMI;
// Emit the correct call instruction based on the type of symbol called.
if (GlobalAddressSDNode *GASD =
if (GlobalAddressSDNode *GASD =
dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
true);
} else if (ExternalSymbolSDNode *ESSDN =
} else if (ExternalSymbolSDNode *ESSDN =
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
true);
} else {
Tmp1 = SelectExpr(N.getOperand(1));
@@ -1081,7 +1081,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
.addReg(PPC::R12);
}
// Load the register args to virtual regs
std::vector<unsigned> ArgVR;
for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
@@ -1112,7 +1112,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
break;
}
}
// Put the call instruction in the correct place in the MachineBasicBlock
BB->push_back(CallMI);
@@ -1140,20 +1140,20 @@ unsigned ISel::SelectExpr(SDOperand N) {
switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break;
case MVT::i32:
BuildMI(BB, PPC::EXTSW, 1, Result).addReg(Tmp1);
BuildMI(BB, PPC::EXTSW, 1, Result).addReg(Tmp1);
break;
case MVT::i16:
BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1);
BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1);
break;
case MVT::i8:
BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1);
BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1);
break;
case MVT::i1:
BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp1).addSImm(0);
break;
}
return Result;
case ISD::CopyFromReg:
if (Result == 1)
Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
@@ -1172,7 +1172,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
BuildMI(BB, PPC::SLD, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
return Result;
case ISD::SRL:
Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
@@ -1184,7 +1184,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
BuildMI(BB, PPC::SRD, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
return Result;
case ISD::SRA:
Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
@@ -1195,7 +1195,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
BuildMI(BB, PPC::SRAD, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
return Result;
case ISD::ADD:
Tmp1 = SelectExpr(N.getOperand(0));
switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
@@ -1302,7 +1302,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1);
}
return Result;
case ISD::MUL:
Tmp1 = SelectExpr(N.getOperand(0));
if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2))
@@ -1338,23 +1338,23 @@ unsigned ISel::SelectExpr(SDOperand N) {
addFrameReference(BuildMI(BB, PPC::LD, 2, Result), FrameIdx);
return Result;
}
case ISD::SETCC:
if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
Opc = SelectSetCR0(N);
unsigned TrueValue = MakeReg(MVT::i32);
BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1);
unsigned FalseValue = MakeReg(MVT::i32);
BuildMI(BB, PPC::LI, 1, FalseValue).addSImm(0);
// Create an iterator with which to insert the MBB for copying the false
// Create an iterator with which to insert the MBB for copying the false
// value and the MBB to hold the PHI instruction for this SetCC.
MachineBasicBlock *thisMBB = BB;
const BasicBlock *LLVM_BB = BB->getBasicBlock();
ilist<MachineBasicBlock>::iterator It = BB;
++It;
// thisMBB:
// ...
// cmpTY cr0, r1, r2
@@ -1387,13 +1387,13 @@ unsigned ISel::SelectExpr(SDOperand N) {
}
assert(0 && "Is this legal?");
return 0;
case ISD::SELECT: {
unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
Opc = SelectSetCR0(N.getOperand(0));
// Create an iterator with which to insert the MBB for copying the false
// Create an iterator with which to insert the MBB for copying the false
// value and the MBB to hold the PHI instruction for this SetCC.
MachineBasicBlock *thisMBB = BB;
const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -1467,7 +1467,7 @@ void ISel::Select(SDOperand N) {
return; // Already selected.
SDNode *Node = N.Val;
switch (Node->getOpcode()) {
default:
Node->dump(); std::cerr << "\n";
@@ -1492,16 +1492,16 @@ void ISel::Select(SDOperand N) {
BuildMI(BB, PPC::B, 1).addMBB(Dest);
return;
}
case ISD::BRCOND:
case ISD::BRCOND:
SelectBranchCC(N);
return;
case ISD::CopyToReg:
Select(N.getOperand(0));
Tmp1 = SelectExpr(N.getOperand(1));
Tmp2 = cast<RegSDNode>(N)->getReg();
if (Tmp1 != Tmp2) {
if (N.getOperand(1).getValueType() == MVT::f64 ||
if (N.getOperand(1).getValueType() == MVT::f64 ||
N.getOperand(1).getValueType() == MVT::f32)
BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1);
else
@@ -1546,8 +1546,8 @@ void ISel::Select(SDOperand N) {
}
BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction
return;
case ISD::TRUNCSTORE:
case ISD::STORE:
case ISD::TRUNCSTORE:
case ISD::STORE:
{
SDOperand Chain = N.getOperand(0);
SDOperand Value = N.getOperand(1);
@@ -1582,7 +1582,7 @@ void ISel::Select(SDOperand N) {
{
int offset;
bool idx = SelectAddr(Address, Tmp2, offset);
if (idx) {
if (idx) {
Opc = IndexedOpForOp(Opc);
BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
} else {
@@ -1611,6 +1611,6 @@ void ISel::Select(SDOperand N) {
/// description file.
///
FunctionPass *llvm::createPPC64ISelPattern(TargetMachine &TM) {
return new ISel(TM);
return new ISel(TM);
}
+2 -2
View File
@@ -1,10 +1,10 @@
//===- PPC64InstrInfo.cpp - PowerPC64 Instruction Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
+3 -3
View File
@@ -1,10 +1,10 @@
//===- PPC64InstrInfo.h - PowerPC64 Instruction Information -----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC64 implementation of the TargetInstrInfo class.
@@ -47,7 +47,7 @@ public:
case PPC::BGE: return PPC::BLT;
case PPC::BGT: return PPC::BLE;
case PPC::BLE: return PPC::BGT;
}
}
}
};
+2 -2
View File
@@ -1,10 +1,10 @@
//===- PPC64JITInfo.h - PowerPC/AIX impl. of the JIT interface -*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC/AIX implementation of the TargetJITInfo class.
+21 -21
View File
@@ -1,10 +1,10 @@
//===- PPC64RegisterInfo.cpp - PowerPC64 Register Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC64 implementation of the MRegisterInfo class.
@@ -38,7 +38,7 @@ namespace llvm {
PPC64RegisterInfo::PPC64RegisterInfo()
: PPC64GenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) {
ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX;
ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX;
ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX;
ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX;
ImmToIdxMap[PPC::LWZ] = PPC::LWZX; ImmToIdxMap[PPC::LWA] = PPC::LWAX;
@@ -62,7 +62,7 @@ static unsigned getIdx(const TargetRegisterClass *RC) {
case 1: return 0;
case 2: return 1;
case 4: return 2;
case 8: return 3;
case 8: return 3;
}
} else if (RC == PPC64::FPRCRegisterClass) {
switch (RC->getSize()) {
@@ -75,12 +75,12 @@ static unsigned getIdx(const TargetRegisterClass *RC) {
abort();
}
void
void
PPC64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, int FrameIdx) const {
static const unsigned Opcode[] = {
PPC::STB, PPC::STH, PPC::STW, PPC::STD, PPC::STFS, PPC::STFD
static const unsigned Opcode[] = {
PPC::STB, PPC::STH, PPC::STW, PPC::STD, PPC::STFS, PPC::STFD
};
unsigned OC = Opcode[getIdx(getClass(SrcReg))];
if (SrcReg == PPC::LR) {
@@ -97,8 +97,8 @@ void
PPC64RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIdx) const{
static const unsigned Opcode[] = {
PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LD, PPC::LFS, PPC::LFD
static const unsigned Opcode[] = {
PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LD, PPC::LFS, PPC::LFD
};
unsigned OC = Opcode[getIdx(getClass(DestReg))];
if (DestReg == PPC::LR) {
@@ -121,7 +121,7 @@ void PPC64RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
} else if (RC == PPC64::FPRCRegisterClass) {
BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
} else {
} else {
std::cerr << "Attempt to copy register that is not GPR or FPR";
abort();
}
@@ -155,7 +155,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// alignment boundary.
unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
// Replace the pseudo instruction with a new instruction...
if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) {
MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
@@ -176,7 +176,7 @@ PPC64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
while (!MI.getOperand(i).isFrameIndex()) {
++i;
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
@@ -198,7 +198,7 @@ PPC64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
// SP before having the stack size subtracted from it, then add the stack size
// to Offset to get the correct offset.
Offset += MF.getFrameInfo()->getStackSize();
if (Offset > 32767 || Offset < -32768) {
// Insert a set of r0 with the full offset value before the ld, st, or add
MachineBasicBlock *MBB = MI.getParent();
@@ -208,7 +208,7 @@ PPC64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
// convert into indexed form of the instruction
// sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
// addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
unsigned NewOpcode =
unsigned NewOpcode =
const_cast<std::map<unsigned, unsigned>& >(ImmToIdxMap)[MI.getOpcode()];
assert(NewOpcode && "No indexed form of load or store available!");
MI.setOpcode(NewOpcode);
@@ -226,15 +226,15 @@ void PPC64RegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineInstr *MI;
// Get the number of bytes to allocate from the FrameInfo
unsigned NumBytes = MFI->getStackSize();
// If we have calls, we cannot use the red zone to store callee save registers
// and we must set up a stack frame, so calculate the necessary size here.
if (MFI->hasCalls()) {
// We reserve argument space for call sites in the function immediately on
// entry to the current function. This eliminates the need for add/sub
// We reserve argument space for call sites in the function immediately on
// entry to the current function. This eliminates the need for add/sub
// brackets around call sites.
NumBytes += MFI->getMaxCallFrameSize();
}
@@ -242,7 +242,7 @@ void PPC64RegisterInfo::emitPrologue(MachineFunction &MF) const {
// Do we need to allocate space on the stack?
if (NumBytes == 0) return;
// Add the size of R1 to NumBytes size for the store of R1 to the bottom
// Add the size of R1 to NumBytes size for the store of R1 to the bottom
// of the stack and round the size to a multiple of the alignment.
unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
unsigned GPRSize = getSpillSize(PPC::R1)/8;
@@ -266,7 +266,7 @@ void PPC64RegisterInfo::emitPrologue(MachineFunction &MF) const {
MI = BuildMI(PPC::STDUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
MBB.insert(MBBI, MI);
}
if (hasFP(MF)) {
MI = BuildMI(PPC::STD, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1);
MBB.insert(MBBI, MI);
@@ -282,7 +282,7 @@ void PPC64RegisterInfo::emitEpilogue(MachineFunction &MF,
MachineInstr *MI;
assert(MBBI->getOpcode() == PPC::BLR &&
"Can only insert epilog into returning blocks");
// Get the number of bytes allocated from the FrameInfo...
unsigned NumBytes = MFI->getStackSize();
@@ -314,7 +314,7 @@ PPC64RegisterInfo::getRegClassForType(const Type* Ty) const {
case Type::PointerTyID:
case Type::LongTyID:
case Type::ULongTyID: return &GPRCInstance;
case Type::FloatTyID:
case Type::DoubleTyID: return &FPRCInstance;
}
+3 -3
View File
@@ -1,10 +1,10 @@
//===- PPC64RegisterInfo.h - PowerPC64 Register Information Impl -*- C++ -*-==//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the MRegisterInfo class.
@@ -36,7 +36,7 @@ public:
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex) const;
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const;
+3 -3
View File
@@ -1,12 +1,12 @@
//===-- PPC64TargetMachine.h - Define TargetMachine for PowerPC64 -*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file declares the PowerPC specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
+39 -39
View File
@@ -1,10 +1,10 @@
//===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
@@ -45,14 +45,14 @@ namespace {
struct PowerPCAsmPrinter : public AsmPrinter {
std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
std::set<std::string> Strings;
PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM)
: AsmPrinter(O, TM), LabelNumber(0) {}
/// Unique incrementer for label values for referencing Global values.
///
unsigned LabelNumber;
virtual const char *getPassName() const {
return "PowerPC Assembly Printer";
}
@@ -109,7 +109,7 @@ namespace {
if (MI->getOperand(OpNo).isImmediate()) {
O << "$+" << MI->getOperand(OpNo).getImmedValue();
} else {
printOp(MI->getOperand(OpNo),
printOp(MI->getOperand(OpNo),
TM.getInstrInfo()->isCall(MI->getOpcode()));
}
}
@@ -158,12 +158,12 @@ namespace {
}
O << 4 * RegNo + value;
}
virtual void printConstantPool(MachineConstantPool *MCP) = 0;
virtual bool runOnMachineFunction(MachineFunction &F) = 0;
virtual bool runOnMachineFunction(MachineFunction &F) = 0;
virtual bool doFinalization(Module &M) = 0;
};
/// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
/// X
///
@@ -183,10 +183,10 @@ namespace {
}
void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
bool runOnMachineFunction(MachineFunction &F);
bool doFinalization(Module &M);
};
/// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
///
struct AIXAsmPrinter : public PowerPCAsmPrinter {
@@ -202,13 +202,13 @@ namespace {
Data64bitsDirective = 0; // we can't emit a 64-bit unit
AlignmentIsInBytes = false; // Alignment is by power of 2.
}
virtual const char *getPassName() const {
return "AIX PPC Assembly Printer";
}
void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
};
@@ -258,7 +258,7 @@ namespace {
/// SwitchStringSection - manage the changes required to output bytes as
/// characters in a string vs. numeric decimal values
///
///
static inline void SwitchStringSection(std::ostream &O, StringSection NewSect,
StringSection &Current) {
if (Current == None) {
@@ -269,7 +269,7 @@ static inline void SwitchStringSection(std::ostream &O, StringSection NewSect,
} else if (Current == Alpha) {
if (NewSect == None)
O << "\"";
else if (NewSect == Numeric)
else if (NewSect == Numeric)
O << "\"\n"
<< "\t.byte ";
} else if (Current == Numeric) {
@@ -310,8 +310,8 @@ static void printAsCString(std::ostream &O, const ConstantArray *CVA) {
O << '\n';
}
/// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly
/// code for a MachineFunction to the given output stream, in a format that the
/// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly
/// code for a MachineFunction to the given output stream, in a format that the
/// Darwin assembler can deal with.
///
FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o, TargetMachine &tm) {
@@ -319,7 +319,7 @@ FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o, TargetMachine &tm) {
}
/// createAIXAsmPrinterPass - Returns a pass that prints the PPC assembly code
/// for a MachineFunction to the given output stream, in a format that the
/// for a MachineFunction to the given output stream, in a format that the
/// AIX 5L assembler can deal with.
///
FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, TargetMachine &tm) {
@@ -332,7 +332,7 @@ FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, TargetMachine &tm) {
void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
int new_symbol;
switch (MO.getType()) {
case MachineOperand::MO_VirtualRegister:
if (Value *V = MO.getVRegValueOrNull()) {
@@ -355,7 +355,7 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs";
abort();
return;
case MachineOperand::MO_MachineBasicBlock: {
MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
@@ -391,7 +391,7 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
O << "L" << Name << "$stub";
return;
}
// External or weakly linked global variables need non-lazily-resolved stubs
if ((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())){
if (GV->hasLinkOnceLinkage())
@@ -405,7 +405,7 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
O << Mang->getValueName(GV);
return;
}
default:
O << "<unknown operand type: " << MO.getType() << ">";
return;
@@ -431,17 +431,17 @@ void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
SH = 32-SH;
}
if (FoundMnemonic) {
printOperand(MI, 0, MVT::i64);
O << ", ";
printOperand(MI, 1, MVT::i64);
printOperand(MI, 0, MVT::i64);
O << ", ";
printOperand(MI, 1, MVT::i64);
O << ", " << (unsigned int)SH << "\n";
return;
}
}
if (printInstruction(MI))
return; // Printer was automatically generated
assert(0 && "Unhandled instruction in asm writer!");
abort();
return;
@@ -490,7 +490,7 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
void DarwinAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
if (CP.empty()) return;
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
@@ -516,13 +516,13 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
unsigned Align = TD.getTypeAlignmentShift(C->getType());
if (C->isNullValue() && /* FIXME: Verify correct */
(I->hasInternalLinkage() || I->hasWeakLinkage() ||
(I->hasInternalLinkage() || I->hasWeakLinkage() ||
I->hasLinkOnceLinkage())) {
SwitchSection(O, CurSection, ".data");
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (I->hasInternalLinkage())
O << ".lcomm " << name << "," << Size << "," << Align;
else
else
O << ".comm " << name << "," << Size;
O << "\t\t; ";
WriteAsOperand(O, I, true, true, &M);
@@ -535,7 +535,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
<< ".private_extern " << name << '\n'
<< ".section __DATA,__datacoal_nt,coalesced,no_toc\n";
LinkOnceStubs.insert(name);
break;
break;
case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
// Nonnull linkonce -> weak
O << "\t.weak " << name << "\n";
@@ -568,7 +568,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
}
// Output stubs for dynamically-linked functions
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i)
{
O << ".data\n";
@@ -597,22 +597,22 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
// Output stubs for external global variables
if (GVStubs.begin() != GVStubs.end())
O << ".data\n.non_lazy_symbol_pointer\n";
for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
i != e; ++i) {
O << "L" << *i << "$non_lazy_ptr:\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\t.long\t0\n";
}
// Output stubs for link-once variables
if (LinkOnceStubs.begin() != LinkOnceStubs.end())
O << ".data\n.align 2\n";
for (std::set<std::string>::iterator i = LinkOnceStubs.begin(),
for (std::set<std::string>::iterator i = LinkOnceStubs.begin(),
e = LinkOnceStubs.end(); i != e; ++i) {
O << "L" << *i << "$non_lazy_ptr:\n"
<< "\t.long\t" << *i << '\n';
}
AsmPrinter::doFinalization(M);
return false; // success
}
@@ -672,7 +672,7 @@ bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
void AIXAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
if (CP.empty()) return;
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
@@ -689,7 +689,7 @@ bool AIXAsmPrinter::doInitialization(Module &M) {
const TargetData &TD = TM.getTargetData();
std::string CurSection;
O << "\t.machine \"ppc64\"\n"
O << "\t.machine \"ppc64\"\n"
<< "\t.toc\n"
<< "\t.csect .text[PR]\n";
@@ -697,11 +697,11 @@ bool AIXAsmPrinter::doInitialization(Module &M) {
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
if (!I->hasInitializer())
continue;
std::string Name = I->getName();
Constant *C = I->getInitializer();
// N.B.: We are defaulting to writable strings
if (I->hasExternalLinkage()) {
if (I->hasExternalLinkage()) {
O << "\t.globl " << Name << '\n'
<< "\t.csect .data[RW],3\n";
} else {
+13 -13
View File
@@ -1,13 +1,13 @@
//===-- PowerPCBranchSelector.cpp - Emit long conditional branches-*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Nate Baegeman and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains a pass that scans a machine function to determine which
// This file contains a pass that scans a machine function to determine which
// conditional branches need more than 16 bits of displacement to reach their
// target basic block. It does this in two passes; a calculation of basic block
// positions pass, and a branch psuedo op to machine branch opcode pass. This
@@ -30,32 +30,32 @@ namespace {
// OffsetMap - Mapping between BB and byte offset from start of function
std::map<MachineBasicBlock*, unsigned> OffsetMap;
/// bytesForOpcode - A convenience function for totalling up the number of
/// bytesForOpcode - A convenience function for totalling up the number of
/// bytes in a basic block.
///
static unsigned bytesForOpcode(unsigned opcode) {
switch (opcode) {
case PPC::COND_BRANCH:
// while this will be 4 most of the time, if we emit 12 it is just a
// minor pessimization that saves us from having to worry about
// minor pessimization that saves us from having to worry about
// keeping the offsets up to date later when we emit long branch glue.
return 12;
case PPC::IMPLICIT_DEF: // no asm emitted
return 0;
break;
default:
default:
return 4; // PowerPC instructions are all 4 bytes
break;
}
}
virtual bool runOnMachineFunction(MachineFunction &Fn) {
// Running total of instructions encountered since beginning of function
unsigned ByteCount = 0;
// For each MBB, add its offset to the offset map, and count up its
// instructions
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
++MFI) {
MachineBasicBlock *MBB = MFI;
OffsetMap[MBB] = ByteCount;
@@ -80,10 +80,10 @@ namespace {
// b .L_TARGET_MBB
// b .L_FALLTHROUGH_MBB
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
++MFI) {
MachineBasicBlock *MBB = MFI;
for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
MBBI != EE; ++MBBI) {
if (MBBI->getOpcode() == PPC::COND_BRANCH) {
@@ -92,11 +92,11 @@ namespace {
// 1. bc opcode
// 2. target MBB
// 3. fallthrough MBB
MachineBasicBlock *trueMBB =
MachineBasicBlock *trueMBB =
MBBI->getOperand(2).getMachineBasicBlock();
MachineBasicBlock *falseMBB =
MachineBasicBlock *falseMBB =
MBBI->getOperand(3).getMachineBasicBlock();
int Displacement = OffsetMap[trueMBB] - ByteCount;
unsigned Opcode = MBBI->getOperand(1).getImmedValue();
unsigned Inverted = PPC32InstrInfo::invertPPCBranchOpcode(Opcode);
+28 -28
View File
@@ -1,12 +1,12 @@
//===-- PPC32CodeEmitter.cpp - JIT Code Emitter for PowerPC32 -----*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
// JIT-compile bytecode to native PowerPC.
//
@@ -42,7 +42,7 @@ namespace {
int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
public:
PPC32CodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
PPC32CodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
: TM(T), MCE(M) {}
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
@@ -58,7 +58,7 @@ namespace {
/// emitWord - write a 32-bit word to memory at the current PC
///
void emitWord(unsigned w) { MCE.emitWord(w); }
/// getValueBit - return the particular bit of Val
///
unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
@@ -80,7 +80,7 @@ namespace {
bool PPC32TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
MachineCodeEmitter &MCE) {
// Machine code emitter pass for PowerPC
PM.add(new PPC32CodeEmitter(*this, MCE));
PM.add(new PPC32CodeEmitter(*this, MCE));
// Delete machine code for this function after emitting it
PM.add(createMachineCodeDeleter());
return false;
@@ -102,7 +102,7 @@ bool PPC32CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
<< "\n");
unsigned Instr = *Ref;
intptr_t BranchTargetDisp = (Location - (intptr_t)Ref) >> 2;
switch (Instr >> 26) {
default: assert(0 && "Unknown branch user!");
case 18: // This is B or BL
@@ -142,36 +142,36 @@ void PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
static unsigned enumRegToMachineReg(unsigned enumReg) {
switch (enumReg) {
case PPC::R0 : case PPC::F0 : case PPC::CR0: return 0;
case PPC::R1 : case PPC::F1 : case PPC::CR1: return 1;
case PPC::R0 : case PPC::F0 : case PPC::CR0: return 0;
case PPC::R1 : case PPC::F1 : case PPC::CR1: return 1;
case PPC::R2 : case PPC::F2 : case PPC::CR2: return 2;
case PPC::R3 : case PPC::F3 : case PPC::CR3: return 3;
case PPC::R4 : case PPC::F4 : case PPC::CR4: return 4;
case PPC::R3 : case PPC::F3 : case PPC::CR3: return 3;
case PPC::R4 : case PPC::F4 : case PPC::CR4: return 4;
case PPC::R5 : case PPC::F5 : case PPC::CR5: return 5;
case PPC::R6 : case PPC::F6 : case PPC::CR6: return 6;
case PPC::R7 : case PPC::F7 : case PPC::CR7: return 7;
case PPC::R6 : case PPC::F6 : case PPC::CR6: return 6;
case PPC::R7 : case PPC::F7 : case PPC::CR7: return 7;
case PPC::R8 : case PPC::F8 : return 8;
case PPC::R9 : case PPC::F9 : return 9;
case PPC::R10: case PPC::F10: return 10;
case PPC::R9 : case PPC::F9 : return 9;
case PPC::R10: case PPC::F10: return 10;
case PPC::R11: case PPC::F11: return 11;
case PPC::R12: case PPC::F12: return 12;
case PPC::R13: case PPC::F13: return 13;
case PPC::R12: case PPC::F12: return 12;
case PPC::R13: case PPC::F13: return 13;
case PPC::R14: case PPC::F14: return 14;
case PPC::R15: case PPC::F15: return 15;
case PPC::R16: case PPC::F16: return 16;
case PPC::R15: case PPC::F15: return 15;
case PPC::R16: case PPC::F16: return 16;
case PPC::R17: case PPC::F17: return 17;
case PPC::R18: case PPC::F18: return 18;
case PPC::R19: case PPC::F19: return 19;
case PPC::R18: case PPC::F18: return 18;
case PPC::R19: case PPC::F19: return 19;
case PPC::R20: case PPC::F20: return 20;
case PPC::R21: case PPC::F21: return 21;
case PPC::R22: case PPC::F22: return 22;
case PPC::R23: case PPC::F23: return 23;
case PPC::R22: case PPC::F22: return 22;
case PPC::R23: case PPC::F23: return 23;
case PPC::R24: case PPC::F24: return 24;
case PPC::R25: case PPC::F25: return 25;
case PPC::R26: case PPC::F26: return 26;
case PPC::R25: case PPC::F25: return 25;
case PPC::R26: case PPC::F26: return 26;
case PPC::R27: case PPC::F27: return 27;
case PPC::R28: case PPC::F28: return 28;
case PPC::R29: case PPC::F29: return 29;
case PPC::R28: case PPC::F28: return 28;
case PPC::R29: case PPC::F29: return 29;
case PPC::R30: case PPC::F30: return 30;
case PPC::R31: case PPC::F31: return 31;
default:
@@ -181,7 +181,7 @@ static unsigned enumRegToMachineReg(unsigned enumReg) {
}
int PPC32CodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
int rv = 0; // Return value; defaults to 0 for unhandled cases
// or things that get fixed up later by the JIT.
if (MO.isRegister()) {
+3 -3
View File
@@ -1,10 +1,10 @@
//===-- PowerPCFrameInfo.h - Define TargetFrameInfo for PowerPC -*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
@@ -22,7 +22,7 @@ namespace llvm {
class PowerPCFrameInfo: public TargetFrameInfo {
const TargetMachine &TM;
std::pair<unsigned, int> LR[1];
public:
PowerPCFrameInfo(const TargetMachine &tm, bool LP64)
: TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0), TM(tm) {
+135 -135
View File
@@ -4,7 +4,7 @@
//
// This file was developed by Nate Begeman and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file defines a pattern matching instruction selector for 32 bit PowerPC.
@@ -47,7 +47,7 @@ namespace {
addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass);
addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
// PowerPC has no intrinsics for these particular operations
setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
setOperationAction(ISD::MEMSET, MVT::Other, Expand);
@@ -56,14 +56,14 @@ namespace {
// PowerPC has an i16 but no i8 (or i1) SEXTLOAD
setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
// PowerPC has no SREM/UREM instructions
setOperationAction(ISD::SREM, MVT::i32, Expand);
setOperationAction(ISD::UREM, MVT::i32, Expand);
setSetCCResultContents(ZeroOrOneSetCCResult);
addLegalFPImmediate(+0.0); // Necessary for FSEL
addLegalFPImmediate(-0.0); //
addLegalFPImmediate(-0.0); //
computeRegisterProperties();
}
@@ -72,16 +72,16 @@ namespace {
/// lower the arguments for the specified function, into the specified DAG.
virtual std::vector<SDOperand>
LowerArguments(Function &F, SelectionDAG &DAG);
/// LowerCallTo - This hook lowers an abstract call to a function into an
/// actual call.
virtual std::pair<SDOperand, SDOperand>
LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand>
LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
virtual std::pair<SDOperand,SDOperand>
LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
const Type *ArgTy, SelectionDAG &DAG);
@@ -102,8 +102,8 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineBasicBlock& BB = MF.front();
std::vector<SDOperand> ArgValues;
// Due to the rather complicated nature of the PowerPC ABI, rather than a
// Due to the rather complicated nature of the PowerPC ABI, rather than a
// fixed size array of physical args, for the sake of simplicity let the STL
// handle tracking them for us.
std::vector<unsigned> argVR, argPR, argOp;
@@ -111,7 +111,7 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
unsigned GPR_remaining = 8;
unsigned FPR_remaining = 13;
unsigned GPR_idx = 0, FPR_idx = 0;
static const unsigned GPR[] = {
static const unsigned GPR[] = {
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
};
@@ -129,13 +129,13 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
bool needsLoad = false;
bool ArgLive = !I->use_empty();
MVT::ValueType ObjectVT = getValueType(I->getType());
switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!");
case MVT::i1:
case MVT::i8:
case MVT::i16:
case MVT::i32:
case MVT::i32:
ObjSize = 4;
if (!ArgLive) break;
if (GPR_remaining > 0) {
@@ -170,7 +170,7 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi);
newroot = argLo;
} else {
needsLoad = true;
needsLoad = true;
}
break;
case MVT::f32:
@@ -179,7 +179,7 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
if (!ArgLive) break;
if (FPR_remaining > 0) {
MF.addLiveIn(FPR[FPR_idx]);
argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT,
argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT,
DAG.getRoot());
--FPR_remaining;
++FPR_idx;
@@ -188,20 +188,20 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
}
break;
}
// We need to load the argument to a virtual register if we determined above
// that we ran out of physical registers of the appropriate type
// that we ran out of physical registers of the appropriate type
if (needsLoad) {
unsigned SubregOffset = 0;
if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3;
if (ObjectVT == MVT::i16) SubregOffset = 2;
int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN,
FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN,
DAG.getConstant(SubregOffset, MVT::i32));
argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN);
}
// Every 4 bytes of argument space consumes one of the GPRs available for
// argument passing.
if (GPR_remaining > 0) {
@@ -212,7 +212,7 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
ArgOffset += ObjSize;
if (newroot.Val)
DAG.setRoot(newroot.getValue(1));
ArgValues.push_back(argt);
}
@@ -228,7 +228,7 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
MF.addLiveIn(GPR[GPR_idx]);
SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot());
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
Val, FIN);
MemOps.push_back(Store);
// Increment the address by four for the next argument to store
@@ -292,8 +292,8 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
NumBytes += 8;
break;
}
// Just to be safe, we'll always reserve the full 24 bytes of linkage area
// Just to be safe, we'll always reserve the full 24 bytes of linkage area
// plus 32 bytes of argument space in case any called code gets funky on us.
if (NumBytes < 56) NumBytes = 56;
@@ -307,7 +307,7 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
// passing.
SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32,
DAG.getEntryNode());
// Figure out which arguments are going to go in registers, and which in
// memory. Also, if this is a vararg function, floating point operations
// must be stored to our stack, and loaded into integer regs as well, if
@@ -315,7 +315,7 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
unsigned ArgOffset = 24;
unsigned GPR_remaining = 8;
unsigned FPR_remaining = 13;
std::vector<SDOperand> MemOps;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
// PtrOff will be used to store the current argument to the stack if a
@@ -323,7 +323,7 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
MVT::ValueType ArgVT = getValueType(Args[i].second);
switch (ArgVT) {
default: assert(0 && "Unexpected ValueType for argument!");
case MVT::i1:
@@ -351,9 +351,9 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
// in it, and store the other half to the stack. If we have two or more
// free GPRs, then we can pass both halves of the i64 in registers.
if (GPR_remaining > 0) {
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
Args[i].first, DAG.getConstant(1, MVT::i32));
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
Args[i].first, DAG.getConstant(0, MVT::i32));
args_to_use.push_back(Hi);
--GPR_remaining;
@@ -420,14 +420,14 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
if (!MemOps.empty())
Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
}
std::vector<MVT::ValueType> RetVals;
MVT::ValueType RetTyVT = getValueType(RetTy);
if (RetTyVT != MVT::isVoid)
RetVals.push_back(RetTyVT);
RetVals.push_back(MVT::Other);
SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
Chain, Callee, args_to_use), 0);
Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
@@ -462,7 +462,7 @@ LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
}
return std::make_pair(Result, Chain);
}
std::pair<SDOperand, SDOperand> PPC32TargetLowering::
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
@@ -484,7 +484,7 @@ class ISel : public SelectionDAGISel {
SelectionDAG *ISelDAG; // Hack to support us having a dag->dag transform
// for sdiv and udiv until it is put into the future
// dag combiner.
/// ExprMap - As shared expressions are codegen'd, we keep track of which
/// vreg the value is produced in, so we only emit one copy of each compiled
/// tree.
@@ -496,15 +496,15 @@ class ISel : public SelectionDAGISel {
public:
ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM),
ISelDAG(0) {}
/// runOnFunction - Override this function in order to reset our per-function
/// variables.
virtual bool runOnFunction(Function &Fn) {
// Make sure we re-emit a set of the global base reg if necessary
GlobalBaseInitialized = false;
return SelectionDAGISel::runOnFunction(Fn);
}
}
/// InstructionSelectBasicBlock - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
@@ -512,7 +512,7 @@ public:
// Codegen the basic block.
ISelDAG = &DAG;
Select(DAG.getRoot());
// Clear state used for selection.
ExprMap.clear();
ISelDAG = 0;
@@ -521,7 +521,7 @@ public:
// dag -> dag expanders for integer divide by constant
SDOperand BuildSDIVSequence(SDOperand N);
SDOperand BuildUDIVSequence(SDOperand N);
unsigned getGlobalBaseReg();
unsigned getConstDouble(double floatVal, unsigned Result);
void MoveCRtoGPR(unsigned CCReg, bool Inv, unsigned Idx, unsigned Result);
@@ -532,7 +532,7 @@ public:
unsigned SelectExpr(SDOperand N, bool Recording=false);
unsigned SelectExprFP(SDOperand N, unsigned Result);
void Select(SDOperand N);
bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
void SelectBranchCC(SDOperand N);
};
@@ -555,7 +555,7 @@ static unsigned ExactLog2(unsigned Val) {
// not, since all 1's are not contiguous.
static bool IsRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
bool isRun = true;
MB = 0;
MB = 0;
ME = 0;
// look for first set bit
@@ -567,7 +567,7 @@ static bool IsRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
break;
}
}
// look for last set bit
for (; i < 32; i++) {
if ((Val & (1 << (31 - i))) == 0)
@@ -580,7 +580,7 @@ static bool IsRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
if ((Val & (1 << (31 - i))) != 0)
break;
}
// if we exhausted all the bits, we found a match at this point for 0*1*0*
if (i == 32)
return true;
@@ -596,7 +596,7 @@ static bool IsRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
if ((Val & (1 << (31 - i))) == 0)
break;
}
// if we exhausted all the bits, then we found a match for 1*0*1*, otherwise,
// the value is not a run of ones.
if (i == 32)
@@ -620,7 +620,7 @@ static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
if (N.getOpcode() != ISD::Constant) return 0;
int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
switch(Opcode) {
default: return 0;
case ISD::ADD:
@@ -666,7 +666,7 @@ static bool NodeHasRecordingVariant(unsigned NodeOpcode) {
switch(NodeOpcode) {
default: return false;
case ISD::AND:
case ISD::OR:
case ISD::OR:
return true;
}
}
@@ -715,7 +715,7 @@ static unsigned getCROpForSetCC(unsigned Opcode, bool Inv1, bool Inv2) {
static unsigned getCRIdxForSetCC(unsigned Condition, bool& Inv) {
switch (Condition) {
default: assert(0 && "Unknown condition!"); abort();
case ISD::SETULT:
case ISD::SETULT:
case ISD::SETLT: Inv = false; return 0;
case ISD::SETUGE:
case ISD::SETGE: Inv = true; return 0;
@@ -744,7 +744,7 @@ static unsigned IndexedOpForOp(unsigned Opcode) {
return 0;
}
// Structure used to return the necessary information to codegen an SDIV as
// Structure used to return the necessary information to codegen an SDIV as
// a multiply.
struct ms {
int m; // magic number
@@ -758,14 +758,14 @@ struct mu {
};
/// magic - calculate the magic numbers required to codegen an integer sdiv as
/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1,
/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1,
/// or -1.
static struct ms magic(int d) {
int p;
unsigned int ad, anc, delta, q1, r1, q2, r2, t;
const unsigned int two31 = 2147483648U; // 2^31
struct ms mag;
ad = abs(d);
t = two31 + ((unsigned int)d >> 31);
anc = t - 1 - t%ad; // absolute value of nc
@@ -847,7 +847,7 @@ SDOperand ISel::BuildSDIVSequence(SDOperand N) {
int d = (int)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
ms magics = magic(d);
// Multiply the numerator (operand 0) by the magic value
SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i32, N.getOperand(0),
SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i32, N.getOperand(0),
ISelDAG->getConstant(magics.m, MVT::i32));
// If d > 0 and m < 0, add the numerator
if (d > 0 && magics.m < 0)
@@ -857,10 +857,10 @@ SDOperand ISel::BuildSDIVSequence(SDOperand N) {
Q = ISelDAG->getNode(ISD::SUB, MVT::i32, Q, N.getOperand(0));
// Shift right algebraic if shift value is nonzero
if (magics.s > 0)
Q = ISelDAG->getNode(ISD::SRA, MVT::i32, Q,
Q = ISelDAG->getNode(ISD::SRA, MVT::i32, Q,
ISelDAG->getConstant(magics.s, MVT::i32));
// Extract the sign bit and add it to the quotient
SDOperand T =
SDOperand T =
ISelDAG->getNode(ISD::SRL, MVT::i32, Q, ISelDAG->getConstant(31, MVT::i32));
return ISelDAG->getNode(ISD::ADD, MVT::i32, Q, T);
}
@@ -870,21 +870,21 @@ SDOperand ISel::BuildSDIVSequence(SDOperand N) {
/// multiplying by a magic number. See:
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
SDOperand ISel::BuildUDIVSequence(SDOperand N) {
unsigned d =
unsigned d =
(unsigned)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
mu magics = magicu(d);
// Multiply the numerator (operand 0) by the magic value
SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i32, N.getOperand(0),
SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i32, N.getOperand(0),
ISelDAG->getConstant(magics.m, MVT::i32));
if (magics.a == 0) {
Q = ISelDAG->getNode(ISD::SRL, MVT::i32, Q,
Q = ISelDAG->getNode(ISD::SRL, MVT::i32, Q,
ISelDAG->getConstant(magics.s, MVT::i32));
} else {
SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), Q);
NPQ = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
NPQ = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
ISelDAG->getConstant(1, MVT::i32));
NPQ = ISelDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q);
Q = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
Q = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
ISelDAG->getConstant(magics.s-1, MVT::i32));
}
return Q;
@@ -906,7 +906,7 @@ unsigned ISel::getGlobalBaseReg() {
return GlobalBaseReg;
}
/// getConstDouble - Loads a floating point value into a register, via the
/// getConstDouble - Loads a floating point value into a register, via the
/// Constant Pool. Optionally takes a register in which to load the value.
unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) {
unsigned Tmp1 = MakeReg(MVT::i32);
@@ -920,7 +920,7 @@ unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) {
return Result;
}
/// MoveCRtoGPR - Move CCReg[Idx] to the least significant bit of Result. If
/// MoveCRtoGPR - Move CCReg[Idx] to the least significant bit of Result. If
/// Inv is true, then invert the result.
void ISel::MoveCRtoGPR(unsigned CCReg, bool Inv, unsigned Idx, unsigned Result){
unsigned IntCR = MakeReg(MVT::i32);
@@ -937,7 +937,7 @@ void ISel::MoveCRtoGPR(unsigned CCReg, bool Inv, unsigned Idx, unsigned Result){
}
}
/// SelectBitfieldInsert - turn an or of two masked values into
/// SelectBitfieldInsert - turn an or of two masked values into
/// the rotate left word immediate then mask insert (rlwimi) instruction.
/// Returns true on success, false if the caller still needs to select OR.
///
@@ -951,15 +951,15 @@ bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0;
unsigned Op0Opc = OR.getOperand(0).getOpcode();
unsigned Op1Opc = OR.getOperand(1).getOpcode();
// Verify that we have the correct opcodes
if (ISD::SHL != Op0Opc && ISD::SRL != Op0Opc && ISD::AND != Op0Opc)
return false;
if (ISD::SHL != Op1Opc && ISD::SRL != Op1Opc && ISD::AND != Op1Opc)
return false;
// Generate Mask value for Target
if (ConstantSDNode *CN =
if (ConstantSDNode *CN =
dyn_cast<ConstantSDNode>(OR.getOperand(0).getOperand(1).Val)) {
switch(Op0Opc) {
case ISD::SHL: TgtMask <<= (unsigned)CN->getValue(); break;
@@ -969,30 +969,30 @@ bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
} else {
return false;
}
// Generate Mask value for Insert
if (ConstantSDNode *CN =
if (ConstantSDNode *CN =
dyn_cast<ConstantSDNode>(OR.getOperand(1).getOperand(1).Val)) {
switch(Op1Opc) {
case ISD::SHL:
Amount = CN->getValue();
case ISD::SHL:
Amount = CN->getValue();
InsMask <<= Amount;
if (Op0Opc == ISD::SRL) IsRotate = true;
break;
case ISD::SRL:
Amount = CN->getValue();
InsMask >>= Amount;
case ISD::SRL:
Amount = CN->getValue();
InsMask >>= Amount;
Amount = 32-Amount;
if (Op0Opc == ISD::SHL) IsRotate = true;
break;
case ISD::AND:
case ISD::AND:
InsMask &= (unsigned)CN->getValue();
break;
}
} else {
return false;
}
// Verify that the Target mask and Insert mask together form a full word mask
// and that the Insert mask is a run of set bits (which implies both are runs
// of set bits). Given that, Select the arguments and generate the rlwimi
@@ -1002,7 +1002,7 @@ bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
unsigned Tmp1, Tmp2;
// Check for rotlwi / rotrwi here, a special case of bitfield insert
// where both bitfield halves are sourced from the same value.
if (IsRotate &&
if (IsRotate &&
OR.getOperand(0).getOperand(0) == OR.getOperand(1).getOperand(0)) {
Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Amount)
@@ -1039,12 +1039,12 @@ unsigned ISel::FoldIfWideZeroExtend(SDOperand N) {
unsigned ISel::SelectCC(SDOperand CC, unsigned& Opc, bool &Inv, unsigned& Idx) {
unsigned Result, Tmp1, Tmp2;
bool AlreadySelected = false;
static const unsigned CompareOpcodes[] =
static const unsigned CompareOpcodes[] =
{ PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW };
// Allocate a condition register for this expression
Result = RegMap->createVirtualRegister(PPC32::CRRCRegisterClass);
// If the first operand to the select is a SETCC node, then we can fold it
// into the branch that selects which value to return.
if (SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val)) {
@@ -1054,12 +1054,12 @@ unsigned ISel::SelectCC(SDOperand CC, unsigned& Opc, bool &Inv, unsigned& Idx) {
// Pass the optional argument U to getImmediateForOpcode for SETCC,
// so that it knows whether the SETCC immediate range is signed or not.
if (1 == getImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC,
if (1 == getImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC,
Tmp2, U)) {
// For comparisons against zero, we can implicity set CR0 if a recording
// For comparisons against zero, we can implicity set CR0 if a recording
// variant (e.g. 'or.' instead of 'or') of the instruction that defines
// operand zero of the SetCC node is available.
if (0 == Tmp2 &&
if (0 == Tmp2 &&
NodeHasRecordingVariant(SetCC->getOperand(0).getOpcode()) &&
SetCC->getOperand(0).Val->hasOneUse()) {
RecordSuccess = false;
@@ -1098,7 +1098,7 @@ unsigned ISel::SelectCC(SDOperand CC, unsigned& Opc, bool &Inv, unsigned& Idx) {
return Result;
}
unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
unsigned &Idx) {
bool Inv0, Inv1;
unsigned Idx0, Idx1, CROpc, Opc1, Tmp1, Tmp2;
@@ -1148,7 +1148,7 @@ bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) {
offset = imm;
return false;
}
}
offset = SelectExpr(N.getOperand(1));
return true;
}
@@ -1159,14 +1159,14 @@ bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
void ISel::SelectBranchCC(SDOperand N)
{
MachineBasicBlock *Dest =
MachineBasicBlock *Dest =
cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
bool Inv;
unsigned Opc, CCReg, Idx;
Select(N.getOperand(0)); //chain
CCReg = SelectCC(N.getOperand(1), Opc, Inv, Idx);
// Iterate to the next basic block, unless we're already at the end of the
ilist<MachineBasicBlock>::iterator It = BB, E = BB->getParent()->end();
if (++It == E) It = BB;
@@ -1176,7 +1176,7 @@ void ISel::SelectBranchCC(SDOperand N)
// if necessary by the branch selection pass. Otherwise, emit a standard
// conditional branch.
if (N.getOpcode() == ISD::BRCONDTWOWAY) {
MachineBasicBlock *Fallthrough =
MachineBasicBlock *Fallthrough =
cast<BasicBlockSDNode>(N.getOperand(3))->getBasicBlock();
if (Dest != It) {
BuildMI(BB, PPC::COND_BRANCH, 4).addReg(CCReg).addImm(Opc)
@@ -1221,7 +1221,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
MVT::ValueType VT = SetCC->getOperand(0).getValueType();
unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE
unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1));
if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) {
switch(SetCC->getCondition()) {
@@ -1282,13 +1282,13 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
assert(0 && "Should never get here");
return 0;
}
bool Inv;
unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
unsigned CCReg = SelectCC(N.getOperand(0), Opc, Inv, Tmp3);
// Create an iterator with which to insert the MBB for copying the false
// Create an iterator with which to insert the MBB for copying the false
// value and the MBB to hold the PHI instruction for this SetCC.
MachineBasicBlock *thisMBB = BB;
const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -1328,7 +1328,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
}
case ISD::FNEG:
if (!NoExcessFPPrecision &&
if (!NoExcessFPPrecision &&
ISD::ADD == N.getOperand(0).getOpcode() &&
N.getOperand(0).Val->hasOneUse() &&
ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
@@ -1339,7 +1339,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
} else if (!NoExcessFPPrecision &&
} else if (!NoExcessFPPrecision &&
ISD::ADD == N.getOperand(0).getOpcode() &&
N.getOperand(0).Val->hasOneUse() &&
ISD::MUL == N.getOperand(0).getOperand(1).getOpcode() &&
@@ -1358,23 +1358,23 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
}
return Result;
case ISD::FABS:
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
return Result;
case ISD::FP_ROUND:
assert (DestType == MVT::f32 &&
N.getOperand(0).getValueType() == MVT::f64 &&
assert (DestType == MVT::f32 &&
N.getOperand(0).getValueType() == MVT::f64 &&
"only f64 to f32 conversion supported here");
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1);
return Result;
case ISD::FP_EXTEND:
assert (DestType == MVT::f64 &&
N.getOperand(0).getValueType() == MVT::f32 &&
assert (DestType == MVT::f64 &&
N.getOperand(0).getValueType() == MVT::f32 &&
"only f32 to f64 conversion supported here");
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
@@ -1386,13 +1386,13 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
return Result;
case ISD::ConstantFP: {
ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
Result = getConstDouble(CN->getValue(), Result);
return Result;
}
case ISD::ADD:
if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
N.getOperand(0).Val->hasOneUse()) {
@@ -1460,16 +1460,16 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
case ISD::UINT_TO_FP:
case ISD::SINT_TO_FP: {
assert (N.getOperand(0).getValueType() == MVT::i32
assert (N.getOperand(0).getValueType() == MVT::i32
&& "int to float must operate on i32");
bool IsUnsigned = (ISD::UINT_TO_FP == opcode);
Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into
Tmp3 = MakeReg(MVT::i32); // temp reg to hold the conversion constant
int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
MachineConstantPool *CP = BB->getParent()->getConstantPool();
if (IsUnsigned) {
unsigned ConstF = getConstDouble(0x1.000000p52);
// Store the hi & low halves of the fp value, currently in int regs
@@ -1542,9 +1542,9 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
if (ISD::CopyFromReg == opcode)
DestType = N.getValue(0).getValueType();
if (DestType == MVT::f64 || DestType == MVT::f32)
if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode &&
if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode &&
ISD::UNDEF != opcode && ISD::CALL != opcode)
return SelectExprFP(N, Result);
@@ -1591,7 +1591,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
addFrameReference(BuildMI(BB, PPC::ADDI, 2, Result), (int)Tmp1, 0, false);
return Result;
case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
Tmp1 = MakeReg(MVT::i32);
@@ -1612,7 +1612,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ?
Node->getValueType(0) : cast<MVTSDNode>(Node)->getExtraValueType();
bool sext = (ISD::SEXTLOAD == opcode);
// Make sure we generate both values.
if (Result != 1)
ExprMap[N.getValue(1)] = 1; // Generate the token
@@ -1632,7 +1632,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
case MVT::f32: Opc = PPC::LFS; break;
case MVT::f64: Opc = PPC::LFD; break;
}
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
Tmp1 = MakeReg(MVT::i32);
int CPI = CP->getIndex();
@@ -1655,10 +1655,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
}
return Result;
}
case ISD::CALL: {
unsigned GPR_idx = 0, FPR_idx = 0;
static const unsigned GPR[] = {
static const unsigned GPR[] = {
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
};
@@ -1673,13 +1673,13 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
MachineInstr *CallMI;
// Emit the correct call instruction based on the type of symbol called.
if (GlobalAddressSDNode *GASD =
if (GlobalAddressSDNode *GASD =
dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
true);
} else if (ExternalSymbolSDNode *ESSDN =
} else if (ExternalSymbolSDNode *ESSDN =
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
true);
} else {
Tmp1 = SelectExpr(N.getOperand(1));
@@ -1688,7 +1688,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
.addReg(PPC::R12);
}
// Load the register args to virtual regs
std::vector<unsigned> ArgVR;
for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
@@ -1718,7 +1718,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
break;
}
}
// Put the call instruction in the correct place in the MachineBasicBlock
BB->push_back(CallMI);
@@ -1750,17 +1750,17 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break;
case MVT::i16:
BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1);
BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1);
break;
case MVT::i8:
BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1);
BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1);
break;
case MVT::i1:
BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp1).addSImm(0);
break;
}
return Result;
case ISD::CopyFromReg:
if (Result == 1)
Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
@@ -1779,7 +1779,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
BuildMI(BB, PPC::SLW, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
return Result;
case ISD::SRL:
Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
@@ -1791,7 +1791,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
BuildMI(BB, PPC::SRW, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
return Result;
case ISD::SRA:
Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
@@ -1802,7 +1802,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
BuildMI(BB, PPC::SRAW, 2, Result).addReg(Tmp1).addReg(Tmp2);
}
return Result;
case ISD::ADD:
assert (DestType == MVT::i32 && "Only do arithmetic on i32s!");
Tmp1 = SelectExpr(N.getOperand(0));
@@ -1823,7 +1823,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
case ISD::AND:
if (PPCCRopts) {
if (N.getOperand(0).getOpcode() == ISD::SETCC ||
if (N.getOperand(0).getOpcode() == ISD::SETCC ||
N.getOperand(1).getOpcode() == ISD::SETCC) {
bool Inv;
Tmp1 = SelectCCExpr(N, Opc, Inv, Tmp2);
@@ -1858,12 +1858,12 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
}
RecordSuccess = true;
return Result;
case ISD::OR:
if (SelectBitfieldInsert(N, Result))
return Result;
if (PPCCRopts) {
if (N.getOperand(0).getOpcode() == ISD::SETCC ||
if (N.getOperand(0).getOpcode() == ISD::SETCC ||
N.getOperand(1).getOpcode() == ISD::SETCC) {
bool Inv;
Tmp1 = SelectCCExpr(N, Opc, Inv, Tmp2);
@@ -1951,7 +1951,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1);
}
return Result;
case ISD::MUL:
Tmp1 = SelectExpr(N.getOperand(0));
if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2))
@@ -1992,7 +1992,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
// constants to implement it as a multiply instead.
case 4:
ExprMap.erase(N);
if (opcode == ISD::SDIV)
if (opcode == ISD::SDIV)
return SelectExpr(BuildSDIVSequence(N));
else
return SelectExpr(BuildUDIVSequence(N));
@@ -2080,7 +2080,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
}
return Result+N.ResNo;
}
case ISD::FP_TO_UINT:
case ISD::FP_TO_SINT: {
bool U = (ISD::FP_TO_UINT == opcode);
@@ -2151,10 +2151,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
assert(0 && "Should never get here");
return 0;
}
case ISD::SETCC:
if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
if (ConstantSDNode *CN =
if (ConstantSDNode *CN =
dyn_cast<ConstantSDNode>(SetCC->getOperand(1).Val)) {
// We can codegen setcc op, imm very efficiently compared to a brcond.
// Check for those cases here.
@@ -2226,7 +2226,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
return Result;
}
}
bool Inv;
unsigned CCReg = SelectCC(N, Opc, Inv, Tmp2);
MoveCRtoGPR(CCReg, Inv, Tmp2, Result);
@@ -2234,14 +2234,14 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
}
assert(0 && "Is this legal?");
return 0;
case ISD::SELECT: {
bool Inv;
unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
unsigned CCReg = SelectCC(N.getOperand(0), Opc, Inv, Tmp3);
// Create an iterator with which to insert the MBB for copying the false
// Create an iterator with which to insert the MBB for copying the false
// value and the MBB to hold the PHI instruction for this SetCC.
MachineBasicBlock *thisMBB = BB;
const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -2313,7 +2313,7 @@ void ISel::Select(SDOperand N) {
return; // Already selected.
SDNode *Node = N.Val;
switch (Node->getOpcode()) {
default:
Node->dump(); std::cerr << "\n";
@@ -2338,7 +2338,7 @@ void ISel::Select(SDOperand N) {
BuildMI(BB, PPC::B, 1).addMBB(Dest);
return;
}
case ISD::BRCOND:
case ISD::BRCOND:
case ISD::BRCONDTWOWAY:
SelectBranchCC(N);
return;
@@ -2346,9 +2346,9 @@ void ISel::Select(SDOperand N) {
Select(N.getOperand(0));
Tmp1 = SelectExpr(N.getOperand(1));
Tmp2 = cast<RegSDNode>(N)->getReg();
if (Tmp1 != Tmp2) {
if (N.getOperand(1).getValueType() == MVT::f64 ||
if (N.getOperand(1).getValueType() == MVT::f64 ||
N.getOperand(1).getValueType() == MVT::f32)
BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1);
else
@@ -2393,8 +2393,8 @@ void ISel::Select(SDOperand N) {
}
BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction
return;
case ISD::TRUNCSTORE:
case ISD::STORE:
case ISD::TRUNCSTORE:
case ISD::STORE:
{
SDOperand Chain = N.getOperand(0);
SDOperand Value = N.getOperand(1);
@@ -2428,7 +2428,7 @@ void ISel::Select(SDOperand N) {
{
int offset;
bool idx = SelectAddr(Address, Tmp2, offset);
if (idx) {
if (idx) {
Opc = IndexedOpForOp(Opc);
BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
} else {
@@ -2457,6 +2457,6 @@ void ISel::Select(SDOperand N) {
/// description file.
///
FunctionPass *llvm::createPPC32ISelPattern(TargetMachine &TM) {
return new ISel(TM);
return new ISel(TM);
}
+3 -3
View File
@@ -1,10 +1,10 @@
//===-- PowerPCInstrBuilder.h - Aides for building PPC insts ----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file exposes functions that may be used with BuildMI from the
@@ -30,7 +30,7 @@ namespace llvm {
/// This allows a constant offset to be specified as well...
///
inline const MachineInstrBuilder&
addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0,
addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0,
bool mem = true) {
if (mem)
return MIB.addSImm(Offset).addFrameIndex(FI);
+2 -2
View File
@@ -1,10 +1,10 @@
//===- PPC32InstrInfo.cpp - PowerPC32 Instruction Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
+3 -3
View File
@@ -1,10 +1,10 @@
//===- PPC32InstrInfo.h - PowerPC32 Instruction Information -----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
@@ -47,7 +47,7 @@ public:
case PPC::BGE: return PPC::BLT;
case PPC::BGT: return PPC::BLE;
case PPC::BLE: return PPC::BGT;
}
}
}
};
+11 -11
View File
@@ -1,10 +1,10 @@
//===-- PPC32JITInfo.cpp - Implement the JIT interfaces for the PowerPC ---===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file implements the JIT interfaces for the 32-bit PowerPC target.
@@ -66,9 +66,9 @@ asm(
"stw r11, 280(r1)\n" // Set up a proper stack frame
"stmw r3, 156(r1)\n" // Save all of the integer registers
// Save all call-clobbered FP regs.
"stfd f1, 44(r1)\n" "stfd f2, 52(r1)\n" "stfd f3, 60(r1)\n"
"stfd f4, 68(r1)\n" "stfd f5, 76(r1)\n" "stfd f6, 84(r1)\n"
"stfd f7, 92(r1)\n" "stfd f8, 100(r1)\n" "stfd f9, 108(r1)\n"
"stfd f1, 44(r1)\n" "stfd f2, 52(r1)\n" "stfd f3, 60(r1)\n"
"stfd f4, 68(r1)\n" "stfd f5, 76(r1)\n" "stfd f6, 84(r1)\n"
"stfd f7, 92(r1)\n" "stfd f8, 100(r1)\n" "stfd f9, 108(r1)\n"
"stfd f10, 116(r1)\n" "stfd f11, 124(r1)\n" "stfd f12, 132(r1)\n"
"stfd f13, 140(r1)\n"
@@ -112,7 +112,7 @@ extern "C" void PPC32CompilationCallbackC(unsigned *IntRegs, double *FPRegs) {
CameFromOrig[-1] = CameFromOrigInst;
}
}
// Locate the start of the stub. If this is a short call, adjust backwards
// the short amount, otherwise the full amount.
bool isShortStub = (*CameFromStub >> 26) == 18;
@@ -135,9 +135,9 @@ extern "C" void PPC32CompilationCallbackC(unsigned *IntRegs, double *FPRegs) {
register unsigned *IRR asm ("r2") = IntRegs;
register double *FRR asm ("r3") = FPRegs;
__asm__ __volatile__ (
"lfd f1, 0(%0)\n" "lfd f2, 8(%0)\n" "lfd f3, 16(%0)\n"
"lfd f4, 24(%0)\n" "lfd f5, 32(%0)\n" "lfd f6, 40(%0)\n"
"lfd f7, 48(%0)\n" "lfd f8, 56(%0)\n" "lfd f9, 64(%0)\n"
"lfd f1, 0(%0)\n" "lfd f2, 8(%0)\n" "lfd f3, 16(%0)\n"
"lfd f4, 24(%0)\n" "lfd f5, 32(%0)\n" "lfd f6, 40(%0)\n"
"lfd f7, 48(%0)\n" "lfd f8, 56(%0)\n" "lfd f9, 64(%0)\n"
"lfd f10, 72(%0)\n" "lfd f11, 80(%0)\n" "lfd f12, 88(%0)\n"
"lfd f13, 96(%0)\n"
"lmw r3, 0(%1)\n" // Load all integer regs
@@ -147,13 +147,13 @@ extern "C" void PPC32CompilationCallbackC(unsigned *IntRegs, double *FPRegs) {
"mtctr r0\n" // Put it into the CTR register
"lwz r1,0(r1)\n" // Pop two frames off
"bctr\n" :: // Return to stub!
"b" (FRR), "b" (IRR));
"b" (FRR), "b" (IRR));
#endif
}
TargetJITInfo::LazyResolverFn
TargetJITInfo::LazyResolverFn
PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) {
JITCompilerFunction = Fn;
return PPC32CompilationCallback;
+2 -2
View File
@@ -1,10 +1,10 @@
//===- PowerPCJITInfo.h - PowerPC impl. of the JIT interface ----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetJITInfo class.
+18 -18
View File
@@ -1,10 +1,10 @@
//===- PPC32RegisterInfo.cpp - PowerPC32 Register Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC32 implementation of the MRegisterInfo class.
@@ -38,7 +38,7 @@ namespace llvm {
PPC32RegisterInfo::PPC32RegisterInfo()
: PPC32GenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) {
ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX;
ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX;
ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX;
ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX;
ImmToIdxMap[PPC::LWZ] = PPC::LWZX; ImmToIdxMap[PPC::LWA] = PPC::LWAX;
@@ -79,12 +79,12 @@ static unsigned getIdx(const TargetRegisterClass *RC) {
abort();
}
void
void
PPC32RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, int FrameIdx) const {
static const unsigned Opcode[] = {
PPC::STB, PPC::STH, PPC::STW, PPC::STFS, PPC::STFD
static const unsigned Opcode[] = {
PPC::STB, PPC::STH, PPC::STW, PPC::STFS, PPC::STFD
};
unsigned OC = Opcode[getIdx(getClass(SrcReg))];
if (SrcReg == PPC::LR) {
@@ -102,8 +102,8 @@ void
PPC32RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIdx) const{
static const unsigned Opcode[] = {
PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LFS, PPC::LFD
static const unsigned Opcode[] = {
PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LFS, PPC::LFD
};
unsigned OC = Opcode[getIdx(getClass(DestReg))];
if (DestReg == PPC::LR) {
@@ -163,7 +163,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// alignment boundary.
unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
// Replace the pseudo instruction with a new instruction...
if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) {
MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
@@ -184,7 +184,7 @@ PPC32RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
while (!MI.getOperand(i).isFrameIndex()) {
++i;
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
@@ -206,7 +206,7 @@ PPC32RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
// SP before having the stack size subtracted from it, then add the stack size
// to Offset to get the correct offset.
Offset += MF.getFrameInfo()->getStackSize();
if (Offset > 32767 || Offset < -32768) {
// Insert a set of r0 with the full offset value before the ld, st, or add
MachineBasicBlock *MBB = MI.getParent();
@@ -232,15 +232,15 @@ void PPC32RegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineInstr *MI;
// Get the number of bytes to allocate from the FrameInfo
unsigned NumBytes = MFI->getStackSize();
// If we have calls, we cannot use the red zone to store callee save registers
// and we must set up a stack frame, so calculate the necessary size here.
if (MFI->hasCalls()) {
// We reserve argument space for call sites in the function immediately on
// entry to the current function. This eliminates the need for add/sub
// We reserve argument space for call sites in the function immediately on
// entry to the current function. This eliminates the need for add/sub
// brackets around call sites.
NumBytes += MFI->getMaxCallFrameSize();
}
@@ -248,7 +248,7 @@ void PPC32RegisterInfo::emitPrologue(MachineFunction &MF) const {
// Do we need to allocate space on the stack?
if (NumBytes == 0) return;
// Add the size of R1 to NumBytes size for the store of R1 to the bottom
// Add the size of R1 to NumBytes size for the store of R1 to the bottom
// of the stack and round the size to a multiple of the alignment.
unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
unsigned GPRSize = getSpillSize(PPC::R1)/8;
@@ -272,7 +272,7 @@ void PPC32RegisterInfo::emitPrologue(MachineFunction &MF) const {
MI = BuildMI(PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
MBB.insert(MBBI, MI);
}
if (hasFP(MF)) {
MI = BuildMI(PPC::STW, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1);
MBB.insert(MBBI, MI);
@@ -288,7 +288,7 @@ void PPC32RegisterInfo::emitEpilogue(MachineFunction &MF,
MachineInstr *MI;
assert(MBBI->getOpcode() == PPC::BLR &&
"Can only insert epilog into returning blocks");
// Get the number of bytes allocated from the FrameInfo...
unsigned NumBytes = MFI->getStackSize();
unsigned GPRSize = getSpillSize(PPC::R31)/8;
@@ -319,7 +319,7 @@ PPC32RegisterInfo::getRegClassForType(const Type* Ty) const {
case Type::IntTyID:
case Type::UIntTyID:
case Type::PointerTyID: return &GPRCInstance;
case Type::FloatTyID:
case Type::DoubleTyID: return &FPRCInstance;
}
+3 -3
View File
@@ -1,10 +1,10 @@
//===- PPC32RegisterInfo.h - PowerPC32 Register Information Impl -*- C++ -*-==//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the MRegisterInfo class.
@@ -36,7 +36,7 @@ public:
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex) const;
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const;
+2 -2
View File
@@ -1,10 +1,10 @@
//===- PPC32Relocations.h - PPC32 Code Relocations --------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file defines the PowerPC 32-bit target-specific relocation types.
+16 -16
View File
@@ -1,12 +1,12 @@
//===-- PowerPCTargetMachine.cpp - Define TargetMachine for PowerPC -------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
@@ -31,13 +31,13 @@ using namespace llvm;
namespace llvm {
bool PPCCRopts;
cl::opt<bool> AIX("aix",
cl::desc("Generate AIX/xcoff instead of Darwin/MachO"),
cl::opt<bool> AIX("aix",
cl::desc("Generate AIX/xcoff instead of Darwin/MachO"),
cl::Hidden);
cl::opt<bool> EnablePPCLSR("enable-lsr-for-ppc",
cl::desc("Enable LSR for PPC (beta)"),
cl::opt<bool> EnablePPCLSR("enable-lsr-for-ppc",
cl::desc("Enable LSR for PPC (beta)"),
cl::Hidden);
cl::opt<bool, true> EnablePPCCRopts("enable-cc-opts",
cl::opt<bool, true> EnablePPCCRopts("enable-cc-opts",
cl::desc("Enable opts using condition regs (beta)"),
cl::location(PPCCRopts),
cl::init(false),
@@ -47,13 +47,13 @@ namespace llvm {
namespace {
const std::string PPC32ID = "PowerPC/32bit";
const std::string PPC64ID = "PowerPC/64bit";
// Register the targets
RegisterTarget<PPC32TargetMachine>
RegisterTarget<PPC32TargetMachine>
X("ppc32", " PowerPC 32-bit");
#if 0
RegisterTarget<PPC64TargetMachine>
RegisterTarget<PPC64TargetMachine>
Y("ppc64", " PowerPC 64-bit (unimplemented)");
#endif
}
@@ -84,7 +84,7 @@ bool PowerPCTargetMachine::addPassesToEmitAssembly(PassManager &PM,
PM.add(createLoopStrengthReducePass());
PM.add(createCFGSimplificationPass());
}
// FIXME: Implement efficient support for garbage collection intrinsics.
PM.add(createLowerGCPass());
@@ -116,15 +116,15 @@ bool PowerPCTargetMachine::addPassesToEmitAssembly(PassManager &PM,
PM.add(createMachineFunctionPrinterPass(&std::cerr));
PM.add(createPrologEpilogCodeInserter());
// Must run branch selection immediately preceding the asm printer
PM.add(createPPCBranchSelectionPass());
if (AIX)
PM.add(createAIXAsmPrinter(Out, *this));
else
PM.add(createDarwinAsmPrinter(Out, *this));
PM.add(createMachineCodeDeleter());
return false;
}
@@ -172,7 +172,7 @@ void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
/// PowerPCTargetMachine ctor - Create an ILP32 architecture model
///
PPC32TargetMachine::PPC32TargetMachine(const Module &M, IntrinsicLowering *IL)
: PowerPCTargetMachine(PPC32ID, IL,
: PowerPCTargetMachine(PPC32ID, IL,
TargetData(PPC32ID,false,4,4,4,4,4,4,2,1,1),
PowerPCFrameInfo(*this, false)), JITInfo(*this) {}
+3 -3
View File
@@ -1,12 +1,12 @@
//===-- PPC32TargetMachine.h - Define TargetMachine for PowerPC -*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file declares the PowerPC specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
+3 -3
View File
@@ -1,10 +1,10 @@
//===- PowerPCInstrInfo.h - PowerPC Instruction Information -----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
@@ -23,7 +23,7 @@ namespace llvm {
VMX = 1 << 0,
PPC64 = 1 << 1,
};
enum {
None = 0,
Gpr = 1,
+3 -3
View File
@@ -1,12 +1,12 @@
//===-- PowerPCTargetMachine.h - Define TargetMachine for PowerPC -*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file declares the PowerPC-specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- Skeleton.h - Target private header file -----------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the definitions shared among the various components of the
+2 -2
View File
@@ -1,10 +1,10 @@
//===- SkeletonInstrInfo.cpp - Instruction Information ----------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is where you implement methods for the TargetInstrInfo class.
+3 -3
View File
@@ -1,10 +1,10 @@
//===- SkeletonInstrInfo.h - Instruction Information ------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file is where the target-specific implementation of the TargetInstrInfo
@@ -24,7 +24,7 @@ namespace llvm {
const SkeletonRegisterInfo RI;
public:
SkeletonInstrInfo();
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
/// such, whenever a client has an instance of instruction info, it should
/// always be able to get register info as well (through this method).
+3 -3
View File
@@ -1,12 +1,12 @@
//===-- SkeletonCodeEmitter.cpp - JIT Code Emitter --------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This is a stub for a JIT code generator, which is obviously not implemented.
//
//===----------------------------------------------------------------------===//
+3 -3
View File
@@ -1,10 +1,10 @@
//===- SkeletonJITInfo.h - Skeleton impl of JIT interface -------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the skeleton implementation of the TargetJITInfo class.
@@ -30,7 +30,7 @@ namespace llvm {
/// is not supported for this target.
///
virtual void addPassesToJITCompile(FunctionPassManager &PM);
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
/// overwriting OLD with a branch to NEW. This is used for self-modifying
+4 -4
View File
@@ -1,10 +1,10 @@
//===- SkeletonRegisterInfo.cpp - Skeleton Register Information -*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the Skeleton implementation of the MRegisterInfo class.
@@ -45,7 +45,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
abort();
}
void SkeletonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II)
void SkeletonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II)
const {
abort();
}
@@ -81,7 +81,7 @@ SkeletonRegisterInfo::getRegClassForType(const Type* Ty) const {
case Type::IntTyID:
case Type::UIntTyID:
case Type::PointerTyID: return &GPRCInstance;
case Type::FloatTyID:
case Type::DoubleTyID: return &FPRCInstance;
}
+9 -9
View File
@@ -1,10 +1,10 @@
//===- SkeletonRegisterInfo.h - Skeleton Register Information Impl -*- C++ -*-==//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the Skeleton implementation of the MRegisterInfo class.
@@ -22,27 +22,27 @@ namespace llvm {
struct SkeletonRegisterInfo : public SkeletonGenRegisterInfo {
SkeletonRegisterInfo();
const TargetRegisterClass* getRegClassForType(const Type* Ty) const;
void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned SrcReg, int FrameIndex) const;
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex) const;
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
};
@@ -1,12 +1,12 @@
//===-- SkeletonTargetMachine.cpp - Define TargetMachine for Skeleton -----===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
+4 -4
View File
@@ -1,12 +1,12 @@
//===-- SkeletonTargetMachine.h - TargetMachine for Skeleton ----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file declares the Skeleton specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
@@ -41,7 +41,7 @@ namespace llvm {
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
MachineCodeEmitter &MCE);
virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
};
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- DelaySlotFiller.cpp - SparcV8 delay slot filler -------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is a simple local pass that fills delay slots with NOPs.
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- FPMover.cpp - SparcV8 double-precision floating point move fixer --===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Turns FpMOVD instructions into FMOVS pairs after regalloc.
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- SparcV8.h - Top-level interface for SparcV8 representation -*- C++ -*-//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the entry points for global functions defined in the LLVM
+13 -13
View File
@@ -1,10 +1,10 @@
//===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
@@ -71,7 +71,7 @@ namespace {
void printOperand(const MachineInstr *MI, int opNum);
void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true);
void printMachineInstruction(const MachineInstr *MI);
bool runOnMachineFunction(MachineFunction &F);
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
};
@@ -203,7 +203,7 @@ void V8Printer::emitConstantValueOnly(const Constant *CV) {
// Print a constant value or values, with the appropriate storage class as a
// prefix.
void V8Printer::emitGlobalConstant(const Constant *CV) {
void V8Printer::emitGlobalConstant(const Constant *CV) {
const TargetData &TD = TM.getTargetData();
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
@@ -235,7 +235,7 @@ void V8Printer::emitGlobalConstant(const Constant *CV) {
// Insert the field padding unless it's zero bytes...
if (padSize)
O << "\t.skip\t " << padSize << "\n";
O << "\t.skip\t " << padSize << "\n";
}
assert(sizeSoFar == cvsLayout->StructSize &&
"Layout of constant struct may be incorrect!");
@@ -268,7 +268,7 @@ void V8Printer::emitGlobalConstant(const Constant *CV) {
}
} else if (isa<UndefValue> (CV)) {
unsigned size = TD.getTypeSize (CV->getType ());
O << "\t.skip\t " << size << "\n";
O << "\t.skip\t " << size << "\n";
return;
} else if (isa<ConstantAggregateZero> (CV)) {
unsigned size = TD.getTypeSize (CV->getType ());
@@ -311,7 +311,7 @@ void V8Printer::emitGlobalConstant(const Constant *CV) {
void V8Printer::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
if (CP.empty()) return;
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
@@ -424,7 +424,7 @@ void V8Printer::printOperand(const MachineInstr *MI, int opNum) {
O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
break;
default:
O << "<unknown operand type>"; abort (); break;
O << "<unknown operand type>"; abort (); break;
}
if (CloseParen) O << ")";
}
@@ -511,7 +511,7 @@ void V8Printer::printMachineInstruction(const MachineInstr *MI) {
O << "! ";
O << Desc.Name << " ";
// Printing memory instructions is a special case.
// for loads: %dest = op %base, offset --> op [%base + offset], %dest
// for stores: op %base, offset, %src --> op %src, [%base + offset]
@@ -550,7 +550,7 @@ void V8Printer::printMachineInstruction(const MachineInstr *MI) {
for (unsigned i = 0; i < MI->getNumOperands (); ++i)
if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ())
print_order.push_back (i);
for (unsigned i = 0, e = print_order.size (); i != e; ++i) {
for (unsigned i = 0, e = print_order.size (); i != e; ++i) {
printOperand (MI, print_order[i]);
if (i != (print_order.size () - 1))
O << ", ";
@@ -588,13 +588,13 @@ bool V8Printer::doFinalization(Module &M) {
unsigned Size = TD.getTypeSize(C->getType());
unsigned Align = TD.getTypeAlignment(C->getType());
if (C->isNullValue() &&
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
SwitchSection(O, CurSection, ".data");
if (I->hasInternalLinkage())
O << "\t.local " << name << "\n";
O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
<< "," << (unsigned)TD.getTypeAlignment(C->getType());
O << "\t\t! ";
@@ -609,7 +609,7 @@ bool V8Printer::doFinalization(Module &M) {
SwitchSection(O, CurSection, "");
O << "\t.section\t\".llvm.linkonce.d." << name << "\",\"aw\",@progbits\n";
break;
case GlobalValue::AppendingLinkage:
// FIXME: appending linkage variables should go into a section of
// their name or something. For now, just emit them as external.
+2 -2
View File
@@ -1,10 +1,10 @@
//===- SparcV8InstrInfo.cpp - SparcV8 Instruction Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the TargetInstrInfo class.
+2 -2
View File
@@ -1,10 +1,10 @@
//===- SparcV8InstrInfo.h - SparcV8 Instruction Information -----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the TargetInstrInfo class.
+5 -5
View File
@@ -1,10 +1,10 @@
//===- SparcV8RegisterInfo.cpp - SparcV8 Register Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the MRegisterInfo class.
@@ -44,7 +44,7 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const TargetRegisterClass *RC = getClass(SrcReg);
// On the order of operands here: think "[FrameIdx + 0] = SrcReg".
if (RC == SparcV8::IntRegsRegisterClass)
if (RC == SparcV8::IntRegsRegisterClass)
BuildMI (MBB, I, V8::ST, 3).addFrameIndex (FrameIdx).addSImm (0)
.addReg (SrcReg);
else if (RC == SparcV8::FPRegsRegisterClass)
@@ -61,7 +61,7 @@ void SparcV8RegisterInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FrameIdx) const {
const TargetRegisterClass *RC = getClass(DestReg);
if (RC == SparcV8::IntRegsRegisterClass)
if (RC == SparcV8::IntRegsRegisterClass)
BuildMI (MBB, I, V8::LD, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0);
else if (RC == SparcV8::FPRegsRegisterClass)
BuildMI (MBB, I, V8::LDFri, 2, DestReg).addFrameIndex (FrameIdx)
@@ -77,7 +77,7 @@ void SparcV8RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const {
if (RC == SparcV8::IntRegsRegisterClass)
if (RC == SparcV8::IntRegsRegisterClass)
BuildMI (MBB, I, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
else if (RC == SparcV8::FPRegsRegisterClass)
BuildMI (MBB, I, V8::FMOVS, 1, DestReg).addReg (SrcReg);
+3 -3
View File
@@ -1,10 +1,10 @@
//===- SparcV8RegisterInfo.h - SparcV8 Register Information Impl -*- C++ -*-==//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the MRegisterInfo class.
@@ -33,7 +33,7 @@ struct SparcV8RegisterInfo : public SparcV8GenRegisterInfo {
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex) const;
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const;
+8 -8
View File
@@ -1,12 +1,12 @@
//===-- SparcV8TargetMachine.cpp - Define TargetMachine for SparcV8 -------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
@@ -87,7 +87,7 @@ bool SparcV8TargetMachine::addPassesToEmitAssembly(PassManager &PM,
// Print LLVM code input to instruction selector:
if (PrintMachineCode)
PM.add(new PrintFunctionPass());
PM.add(createSparcV8SimpleInstructionSelector(*this));
// Print machine instructions as they were initially generated.
@@ -126,7 +126,7 @@ void SparcV8JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
// Replace malloc and free instructions with library calls.
PM.add(createLowerAllocationsPass());
// FIXME: implement the switch instruction in the instruction selector.
PM.add(createLowerSwitchPass());
@@ -134,17 +134,17 @@ void SparcV8JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
PM.add(createLowerInvokePass());
PM.add(createLowerConstantExpressionsPass());
// Make sure that no unreachable blocks are instruction selected.
PM.add(createUnreachableBlockEliminationPass());
// FIXME: implement the select instruction in the instruction selector.
PM.add(createLowerSelectPass());
// Print LLVM code input to instruction selector:
if (PrintMachineCode)
PM.add(new PrintFunctionPass());
PM.add(createSparcV8SimpleInstructionSelector(TM));
// Print machine instructions as they were initially generated.
+4 -4
View File
@@ -1,12 +1,12 @@
//===-- SparcV8TargetMachine.h - Define TargetMachine for SparcV8 -*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file declares the SparcV8 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
@@ -52,7 +52,7 @@ public:
///
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
MachineCodeEmitter &MCE);
virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
};
+4 -4
View File
@@ -1,12 +1,12 @@
//===-- SparcV8CodeEmitter.cpp - JIT Code Emitter for SparcV8 -----*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
@@ -78,7 +78,7 @@ bool SparcV8TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
MachineCodeEmitter &MCE) {
// Keep as `true' until this is a functional JIT to allow llvm-gcc to build
return true;
// Machine code emitter pass for SparcV8
PM.add(new SparcV8CodeEmitter(*this, MCE));
// Delete machine code for this function after emitting it
+32 -32
View File
@@ -1,10 +1,10 @@
//===-- InstSelectSimple.cpp - A simple instruction selector for SparcV8 --===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file defines a simple peephole instruction selector for the V8 target
@@ -318,7 +318,7 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addSImm (0);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
// Copy it with a SETHI/OR pair; the JIT + asmwriter should recognize
// that SETHI %reg,global == SETHI %reg,%hi(global) and
// that SETHI %reg,global == SETHI %reg,%hi(global) and
// OR %reg,global,%reg == OR %reg,%lo(global),%reg.
unsigned TmpReg = makeAnotherReg (C->getType ());
BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addGlobalAddress(GV);
@@ -362,10 +362,10 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
const unsigned *IAR = &IncomingArgRegs[0];
unsigned ArgOffset = 68;
// Store registers onto stack if this is a varargs function.
// Store registers onto stack if this is a varargs function.
// FIXME: This doesn't really pertain to "loading arguments into
// virtual registers", so it's not clear that it really belongs here.
// FIXME: We could avoid storing any args onto the stack that don't
// FIXME: We could avoid storing any args onto the stack that don't
// need to be in memory, because they come before the ellipsis in the
// parameter list (and thus could never be accessed through va_arg).
if (LF->getFunctionType ()->isVarArg ()) {
@@ -505,7 +505,7 @@ void V8ISel::SelectPHINodes() {
break;
}
assert (PredMBB && "Couldn't find incoming machine-cfg edge for phi");
unsigned ValReg;
std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
PHIValues.lower_bound(PredMBB);
@@ -515,7 +515,7 @@ void V8ISel::SelectPHINodes() {
// predecessor. Recycle it.
ValReg = EntryIt->second;
} else {
} else {
// Get the incoming value into a virtual register.
//
Value *Val = PN->getIncomingValue(i);
@@ -534,11 +534,11 @@ void V8ISel::SelectPHINodes() {
// might be arbitrarily complex if it is a constant expression),
// just insert the computation at the top of the basic block.
MachineBasicBlock::iterator PI = PredMBB->begin();
// Skip over any PHI nodes though!
while (PI != PredMBB->end() && PI->getOpcode() == V8::PHI)
++PI;
ValReg = getReg(Val, PredMBB, PI);
}
@@ -568,28 +568,28 @@ bool V8ISel::runOnFunction(Function &Fn) {
// First pass over the function, lower any unknown intrinsic functions
// with the IntrinsicLowering class.
LowerUnknownIntrinsicFunctionCalls(Fn);
F = &MachineFunction::construct(&Fn, TM);
// Create all of the machine basic blocks for the function...
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
BB = &F->front();
// Set up a frame object for the return address. This is used by the
// llvm.returnaddress & llvm.frameaddress intrinisics.
//ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
// Copy incoming arguments off of the stack and out of fixed registers.
LoadArgumentsToVirtualRegs(&Fn);
// Instruction select everything except PHI nodes
visit(Fn);
// Select the PHI nodes
SelectPHINodes();
RegMap.clear();
MBBMap.clear();
F = 0;
@@ -632,11 +632,11 @@ void V8ISel::emitFPToIntegerCast (MachineBasicBlock *BB,
const Type *newTy, unsigned DestReg) {
unsigned FPCastOpcode, FPStoreOpcode, FPSize, FPAlign;
unsigned oldTyClass = getClassB(oldTy);
if (oldTyClass == cFloat) {
FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4;
if (oldTyClass == cFloat) {
FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4;
FPAlign = TM.getTargetData().getFloatAlignment();
} else { // it's a double
FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8;
FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8;
FPAlign = TM.getTargetData().getDoubleAlignment();
}
unsigned TempReg = makeAnotherReg (oldTy);
@@ -672,11 +672,11 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
case cShort:
case cInt:
switch (oldTyClass) {
case cLong:
case cLong:
// Treat it like a cast from the lower half of the value.
emitIntegerCast (BB, IP, Type::IntTy, SrcReg+1, newTy, DestReg);
break;
case cFloat:
case cFloat:
case cDouble:
emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
break;
@@ -742,10 +742,10 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
unsigned TempReg = emitIntegerCast (BB, IP, OldHalfTy, SrcReg,
NewHalfTy, DestReg+1, true);
if (newTy->isSigned ()) {
BuildMI (*BB, IP, V8::SRAri, 2, DestReg).addReg (TempReg)
BuildMI (*BB, IP, V8::SRAri, 2, DestReg).addReg (TempReg)
.addZImm (31);
} else {
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0)
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0)
.addReg (V8::G0);
}
break;
@@ -1162,7 +1162,7 @@ void V8ISel::emitGEPOperation (MachineBasicBlock *MBB,
if (isa<ConstantIntegral> (idx)) {
// If idx is a constant, we don't have to emit the multiply.
int64_t Val = cast<ConstantIntegral> (idx)->getRawValue ();
if ((Val * elementSize) + 4096 < 8191) {
if ((Val * elementSize) + 4096 < 8191) {
// (Val * elementSize) is constant and fits in an immediate field.
// emit: nextBasePtrReg = ADDri basePtrReg, (Val * elementSize)
addImmed = true;
@@ -1180,16 +1180,16 @@ void V8ISel::emitGEPOperation (MachineBasicBlock *MBB,
OffsetReg = makeAnotherReg (Type::IntTy);
unsigned idxReg = getReg (idx, MBB, IP);
switch (elementSize) {
case 1:
case 1:
BuildMI (*MBB, IP, V8::ORrr, 2, OffsetReg).addReg (V8::G0).addReg (idxReg);
break;
case 2:
case 2:
BuildMI (*MBB, IP, V8::SLLri, 2, OffsetReg).addReg (idxReg).addZImm (1);
break;
case 4:
case 4:
BuildMI (*MBB, IP, V8::SLLri, 2, OffsetReg).addReg (idxReg).addZImm (2);
break;
case 8:
case 8:
BuildMI (*MBB, IP, V8::SLLri, 2, OffsetReg).addReg (idxReg).addZImm (3);
break;
default: {
@@ -1343,7 +1343,7 @@ void V8ISel::emitShift64 (MachineBasicBlock *MBB,
// ba .lshr_continue
BB = oneShiftMBB;
if (isSigned)
BuildMI (BB, V8::SRAri, 2, OneShiftOutReg).addReg (SrcReg).addZImm (31);
else
@@ -1515,7 +1515,7 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
}
switch (getClassB (I.getType ())) {
case cByte:
case cByte:
if (I.getType ()->isSigned ()) { // add byte
BuildMI (BB, V8::ANDri, 2, DestReg).addReg (ResultReg).addZImm (0xff);
} else { // add ubyte
@@ -1562,7 +1562,7 @@ void V8ISel::visitSetCondInst(SetCondInst &I) {
unsigned Op1Reg = getReg (I.getOperand (1));
unsigned DestReg = getReg (I);
const Type *Ty = I.getOperand (0)->getType ();
// Compare the two values.
if (getClass (Ty) < cLong) {
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
+4 -4
View File
@@ -1,10 +1,10 @@
//===- SparcV8JITInfo.h - SparcV8 impl. of the JIT interface ----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the TargetJITInfo class.
@@ -30,14 +30,14 @@ namespace llvm {
/// is not supported for this target.
///
virtual void addPassesToJITCompile(FunctionPassManager &PM);
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
/// overwriting OLD with a branch to NEW. This is used for self-modifying
/// code.
///
virtual void replaceMachineCodeForFunction(void *Old, void *New);
/// getJITStubForFunction - Create or return a stub for the specified
/// function. This stub acts just like the specified function, except that
/// it allows the "address" of the function to be taken without having to
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- DelaySlotFiller.cpp - SparcV8 delay slot filler -------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is a simple local pass that fills delay slots with NOPs.
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- FPMover.cpp - SparcV8 double-precision floating point move fixer --===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Turns FpMOVD instructions into FMOVS pairs after regalloc.
+2 -2
View File
@@ -1,10 +1,10 @@
//===-- SparcV8.h - Top-level interface for SparcV8 representation -*- C++ -*-//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the entry points for global functions defined in the LLVM
+13 -13
View File
@@ -1,10 +1,10 @@
//===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
@@ -71,7 +71,7 @@ namespace {
void printOperand(const MachineInstr *MI, int opNum);
void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true);
void printMachineInstruction(const MachineInstr *MI);
bool runOnMachineFunction(MachineFunction &F);
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
};
@@ -203,7 +203,7 @@ void V8Printer::emitConstantValueOnly(const Constant *CV) {
// Print a constant value or values, with the appropriate storage class as a
// prefix.
void V8Printer::emitGlobalConstant(const Constant *CV) {
void V8Printer::emitGlobalConstant(const Constant *CV) {
const TargetData &TD = TM.getTargetData();
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
@@ -235,7 +235,7 @@ void V8Printer::emitGlobalConstant(const Constant *CV) {
// Insert the field padding unless it's zero bytes...
if (padSize)
O << "\t.skip\t " << padSize << "\n";
O << "\t.skip\t " << padSize << "\n";
}
assert(sizeSoFar == cvsLayout->StructSize &&
"Layout of constant struct may be incorrect!");
@@ -268,7 +268,7 @@ void V8Printer::emitGlobalConstant(const Constant *CV) {
}
} else if (isa<UndefValue> (CV)) {
unsigned size = TD.getTypeSize (CV->getType ());
O << "\t.skip\t " << size << "\n";
O << "\t.skip\t " << size << "\n";
return;
} else if (isa<ConstantAggregateZero> (CV)) {
unsigned size = TD.getTypeSize (CV->getType ());
@@ -311,7 +311,7 @@ void V8Printer::emitGlobalConstant(const Constant *CV) {
void V8Printer::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
if (CP.empty()) return;
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
@@ -424,7 +424,7 @@ void V8Printer::printOperand(const MachineInstr *MI, int opNum) {
O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
break;
default:
O << "<unknown operand type>"; abort (); break;
O << "<unknown operand type>"; abort (); break;
}
if (CloseParen) O << ")";
}
@@ -511,7 +511,7 @@ void V8Printer::printMachineInstruction(const MachineInstr *MI) {
O << "! ";
O << Desc.Name << " ";
// Printing memory instructions is a special case.
// for loads: %dest = op %base, offset --> op [%base + offset], %dest
// for stores: op %base, offset, %src --> op %src, [%base + offset]
@@ -550,7 +550,7 @@ void V8Printer::printMachineInstruction(const MachineInstr *MI) {
for (unsigned i = 0; i < MI->getNumOperands (); ++i)
if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ())
print_order.push_back (i);
for (unsigned i = 0, e = print_order.size (); i != e; ++i) {
for (unsigned i = 0, e = print_order.size (); i != e; ++i) {
printOperand (MI, print_order[i]);
if (i != (print_order.size () - 1))
O << ", ";
@@ -588,13 +588,13 @@ bool V8Printer::doFinalization(Module &M) {
unsigned Size = TD.getTypeSize(C->getType());
unsigned Align = TD.getTypeAlignment(C->getType());
if (C->isNullValue() &&
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
SwitchSection(O, CurSection, ".data");
if (I->hasInternalLinkage())
O << "\t.local " << name << "\n";
O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
<< "," << (unsigned)TD.getTypeAlignment(C->getType());
O << "\t\t! ";
@@ -609,7 +609,7 @@ bool V8Printer::doFinalization(Module &M) {
SwitchSection(O, CurSection, "");
O << "\t.section\t\".llvm.linkonce.d." << name << "\",\"aw\",@progbits\n";
break;
case GlobalValue::AppendingLinkage:
// FIXME: appending linkage variables should go into a section of
// their name or something. For now, just emit them as external.
+4 -4
View File
@@ -1,12 +1,12 @@
//===-- SparcV8CodeEmitter.cpp - JIT Code Emitter for SparcV8 -----*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
@@ -78,7 +78,7 @@ bool SparcV8TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
MachineCodeEmitter &MCE) {
// Keep as `true' until this is a functional JIT to allow llvm-gcc to build
return true;
// Machine code emitter pass for SparcV8
PM.add(new SparcV8CodeEmitter(*this, MCE));
// Delete machine code for this function after emitting it
+32 -32
View File
@@ -1,10 +1,10 @@
//===-- InstSelectSimple.cpp - A simple instruction selector for SparcV8 --===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file defines a simple peephole instruction selector for the V8 target
@@ -318,7 +318,7 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addSImm (0);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
// Copy it with a SETHI/OR pair; the JIT + asmwriter should recognize
// that SETHI %reg,global == SETHI %reg,%hi(global) and
// that SETHI %reg,global == SETHI %reg,%hi(global) and
// OR %reg,global,%reg == OR %reg,%lo(global),%reg.
unsigned TmpReg = makeAnotherReg (C->getType ());
BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addGlobalAddress(GV);
@@ -362,10 +362,10 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
const unsigned *IAR = &IncomingArgRegs[0];
unsigned ArgOffset = 68;
// Store registers onto stack if this is a varargs function.
// Store registers onto stack if this is a varargs function.
// FIXME: This doesn't really pertain to "loading arguments into
// virtual registers", so it's not clear that it really belongs here.
// FIXME: We could avoid storing any args onto the stack that don't
// FIXME: We could avoid storing any args onto the stack that don't
// need to be in memory, because they come before the ellipsis in the
// parameter list (and thus could never be accessed through va_arg).
if (LF->getFunctionType ()->isVarArg ()) {
@@ -505,7 +505,7 @@ void V8ISel::SelectPHINodes() {
break;
}
assert (PredMBB && "Couldn't find incoming machine-cfg edge for phi");
unsigned ValReg;
std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
PHIValues.lower_bound(PredMBB);
@@ -515,7 +515,7 @@ void V8ISel::SelectPHINodes() {
// predecessor. Recycle it.
ValReg = EntryIt->second;
} else {
} else {
// Get the incoming value into a virtual register.
//
Value *Val = PN->getIncomingValue(i);
@@ -534,11 +534,11 @@ void V8ISel::SelectPHINodes() {
// might be arbitrarily complex if it is a constant expression),
// just insert the computation at the top of the basic block.
MachineBasicBlock::iterator PI = PredMBB->begin();
// Skip over any PHI nodes though!
while (PI != PredMBB->end() && PI->getOpcode() == V8::PHI)
++PI;
ValReg = getReg(Val, PredMBB, PI);
}
@@ -568,28 +568,28 @@ bool V8ISel::runOnFunction(Function &Fn) {
// First pass over the function, lower any unknown intrinsic functions
// with the IntrinsicLowering class.
LowerUnknownIntrinsicFunctionCalls(Fn);
F = &MachineFunction::construct(&Fn, TM);
// Create all of the machine basic blocks for the function...
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
BB = &F->front();
// Set up a frame object for the return address. This is used by the
// llvm.returnaddress & llvm.frameaddress intrinisics.
//ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
// Copy incoming arguments off of the stack and out of fixed registers.
LoadArgumentsToVirtualRegs(&Fn);
// Instruction select everything except PHI nodes
visit(Fn);
// Select the PHI nodes
SelectPHINodes();
RegMap.clear();
MBBMap.clear();
F = 0;
@@ -632,11 +632,11 @@ void V8ISel::emitFPToIntegerCast (MachineBasicBlock *BB,
const Type *newTy, unsigned DestReg) {
unsigned FPCastOpcode, FPStoreOpcode, FPSize, FPAlign;
unsigned oldTyClass = getClassB(oldTy);
if (oldTyClass == cFloat) {
FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4;
if (oldTyClass == cFloat) {
FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4;
FPAlign = TM.getTargetData().getFloatAlignment();
} else { // it's a double
FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8;
FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8;
FPAlign = TM.getTargetData().getDoubleAlignment();
}
unsigned TempReg = makeAnotherReg (oldTy);
@@ -672,11 +672,11 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
case cShort:
case cInt:
switch (oldTyClass) {
case cLong:
case cLong:
// Treat it like a cast from the lower half of the value.
emitIntegerCast (BB, IP, Type::IntTy, SrcReg+1, newTy, DestReg);
break;
case cFloat:
case cFloat:
case cDouble:
emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
break;
@@ -742,10 +742,10 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
unsigned TempReg = emitIntegerCast (BB, IP, OldHalfTy, SrcReg,
NewHalfTy, DestReg+1, true);
if (newTy->isSigned ()) {
BuildMI (*BB, IP, V8::SRAri, 2, DestReg).addReg (TempReg)
BuildMI (*BB, IP, V8::SRAri, 2, DestReg).addReg (TempReg)
.addZImm (31);
} else {
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0)
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0)
.addReg (V8::G0);
}
break;
@@ -1162,7 +1162,7 @@ void V8ISel::emitGEPOperation (MachineBasicBlock *MBB,
if (isa<ConstantIntegral> (idx)) {
// If idx is a constant, we don't have to emit the multiply.
int64_t Val = cast<ConstantIntegral> (idx)->getRawValue ();
if ((Val * elementSize) + 4096 < 8191) {
if ((Val * elementSize) + 4096 < 8191) {
// (Val * elementSize) is constant and fits in an immediate field.
// emit: nextBasePtrReg = ADDri basePtrReg, (Val * elementSize)
addImmed = true;
@@ -1180,16 +1180,16 @@ void V8ISel::emitGEPOperation (MachineBasicBlock *MBB,
OffsetReg = makeAnotherReg (Type::IntTy);
unsigned idxReg = getReg (idx, MBB, IP);
switch (elementSize) {
case 1:
case 1:
BuildMI (*MBB, IP, V8::ORrr, 2, OffsetReg).addReg (V8::G0).addReg (idxReg);
break;
case 2:
case 2:
BuildMI (*MBB, IP, V8::SLLri, 2, OffsetReg).addReg (idxReg).addZImm (1);
break;
case 4:
case 4:
BuildMI (*MBB, IP, V8::SLLri, 2, OffsetReg).addReg (idxReg).addZImm (2);
break;
case 8:
case 8:
BuildMI (*MBB, IP, V8::SLLri, 2, OffsetReg).addReg (idxReg).addZImm (3);
break;
default: {
@@ -1343,7 +1343,7 @@ void V8ISel::emitShift64 (MachineBasicBlock *MBB,
// ba .lshr_continue
BB = oneShiftMBB;
if (isSigned)
BuildMI (BB, V8::SRAri, 2, OneShiftOutReg).addReg (SrcReg).addZImm (31);
else
@@ -1515,7 +1515,7 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
}
switch (getClassB (I.getType ())) {
case cByte:
case cByte:
if (I.getType ()->isSigned ()) { // add byte
BuildMI (BB, V8::ANDri, 2, DestReg).addReg (ResultReg).addZImm (0xff);
} else { // add ubyte
@@ -1562,7 +1562,7 @@ void V8ISel::visitSetCondInst(SetCondInst &I) {
unsigned Op1Reg = getReg (I.getOperand (1));
unsigned DestReg = getReg (I);
const Type *Ty = I.getOperand (0)->getType ();
// Compare the two values.
if (getClass (Ty) < cLong) {
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
+2 -2
View File
@@ -1,10 +1,10 @@
//===- SparcV8InstrInfo.cpp - SparcV8 Instruction Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the TargetInstrInfo class.
+2 -2
View File
@@ -1,10 +1,10 @@
//===- SparcV8InstrInfo.h - SparcV8 Instruction Information -----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the TargetInstrInfo class.
+4 -4
View File
@@ -1,10 +1,10 @@
//===- SparcV8JITInfo.h - SparcV8 impl. of the JIT interface ----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the TargetJITInfo class.
@@ -30,14 +30,14 @@ namespace llvm {
/// is not supported for this target.
///
virtual void addPassesToJITCompile(FunctionPassManager &PM);
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
/// overwriting OLD with a branch to NEW. This is used for self-modifying
/// code.
///
virtual void replaceMachineCodeForFunction(void *Old, void *New);
/// getJITStubForFunction - Create or return a stub for the specified
/// function. This stub acts just like the specified function, except that
/// it allows the "address" of the function to be taken without having to
+5 -5
View File
@@ -1,10 +1,10 @@
//===- SparcV8RegisterInfo.cpp - SparcV8 Register Information ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the MRegisterInfo class.
@@ -44,7 +44,7 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const TargetRegisterClass *RC = getClass(SrcReg);
// On the order of operands here: think "[FrameIdx + 0] = SrcReg".
if (RC == SparcV8::IntRegsRegisterClass)
if (RC == SparcV8::IntRegsRegisterClass)
BuildMI (MBB, I, V8::ST, 3).addFrameIndex (FrameIdx).addSImm (0)
.addReg (SrcReg);
else if (RC == SparcV8::FPRegsRegisterClass)
@@ -61,7 +61,7 @@ void SparcV8RegisterInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FrameIdx) const {
const TargetRegisterClass *RC = getClass(DestReg);
if (RC == SparcV8::IntRegsRegisterClass)
if (RC == SparcV8::IntRegsRegisterClass)
BuildMI (MBB, I, V8::LD, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0);
else if (RC == SparcV8::FPRegsRegisterClass)
BuildMI (MBB, I, V8::LDFri, 2, DestReg).addFrameIndex (FrameIdx)
@@ -77,7 +77,7 @@ void SparcV8RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const {
if (RC == SparcV8::IntRegsRegisterClass)
if (RC == SparcV8::IntRegsRegisterClass)
BuildMI (MBB, I, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
else if (RC == SparcV8::FPRegsRegisterClass)
BuildMI (MBB, I, V8::FMOVS, 1, DestReg).addReg (SrcReg);
+3 -3
View File
@@ -1,10 +1,10 @@
//===- SparcV8RegisterInfo.h - SparcV8 Register Information Impl -*- C++ -*-==//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the SparcV8 implementation of the MRegisterInfo class.
@@ -33,7 +33,7 @@ struct SparcV8RegisterInfo : public SparcV8GenRegisterInfo {
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex) const;
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const;
+8 -8
View File
@@ -1,12 +1,12 @@
//===-- SparcV8TargetMachine.cpp - Define TargetMachine for SparcV8 -------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
@@ -87,7 +87,7 @@ bool SparcV8TargetMachine::addPassesToEmitAssembly(PassManager &PM,
// Print LLVM code input to instruction selector:
if (PrintMachineCode)
PM.add(new PrintFunctionPass());
PM.add(createSparcV8SimpleInstructionSelector(*this));
// Print machine instructions as they were initially generated.
@@ -126,7 +126,7 @@ void SparcV8JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
// Replace malloc and free instructions with library calls.
PM.add(createLowerAllocationsPass());
// FIXME: implement the switch instruction in the instruction selector.
PM.add(createLowerSwitchPass());
@@ -134,17 +134,17 @@ void SparcV8JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
PM.add(createLowerInvokePass());
PM.add(createLowerConstantExpressionsPass());
// Make sure that no unreachable blocks are instruction selected.
PM.add(createUnreachableBlockEliminationPass());
// FIXME: implement the select instruction in the instruction selector.
PM.add(createLowerSelectPass());
// Print LLVM code input to instruction selector:
if (PrintMachineCode)
PM.add(new PrintFunctionPass());
PM.add(createSparcV8SimpleInstructionSelector(TM));
// Print machine instructions as they were initially generated.
+4 -4
View File
@@ -1,12 +1,12 @@
//===-- SparcV8TargetMachine.h - Define TargetMachine for SparcV8 -*- C++ -*-=//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file declares the SparcV8 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
@@ -52,7 +52,7 @@ public:
///
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
MachineCodeEmitter &MCE);
virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
};
+11 -11
View File
@@ -1,10 +1,10 @@
//===- llvm/Transforms/DecomposeMultiDimRefs.cpp - Lower array refs to 1D -===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// DecomposeMultiDimRefs - Convert multi-dimensional references consisting of
@@ -57,28 +57,28 @@ static inline bool isZeroConst (Value *V) {
}
// Function: DecomposeArrayRef()
//
//
// For any GetElementPtrInst with 2 or more array and structure indices:
//
//
// opCode CompositeType* P, [uint|ubyte] idx1, ..., [uint|ubyte] idxN
//
//
// this function generates the following sequence:
//
//
// ptr1 = getElementPtr P, idx1
// ptr2 = getElementPtr ptr1, 0, idx2
// ...
// ptrN-1 = getElementPtr ptrN-2, 0, idxN-1
// opCode ptrN-1, 0, idxN // New-MAI
//
//
// Then it replaces the original instruction with this sequence,
// and replaces all uses of the original instruction with New-MAI.
// If idx1 is 0, we simply omit the first getElementPtr instruction.
//
//
// On return: BBI points to the instruction after the current one
// (whether or not *BBI was replaced).
//
//
// Return value: true if the instruction was replaced; false otherwise.
//
//
bool llvm::DecomposeArrayRef(GetElementPtrInst* GEP) {
if (GEP->getNumIndices() < 2
|| (GEP->getNumIndices() == 2
@@ -97,7 +97,7 @@ bool llvm::DecomposeArrayRef(GetElementPtrInst* GEP) {
User::const_op_iterator OI = GEP->idx_begin(), OE = GEP->idx_end();
for (; OI+1 != OE; ++OI) {
std::vector<Value*> Indices;
// If this is the first index and is 0, skip it and move on!
if (OI == GEP->idx_begin()) {
if (isZeroConst (*OI))
+11 -11
View File
@@ -1,10 +1,10 @@
//===-- EmitBytecodeToAssembly.cpp - Emit bytecode to SparcV9 .s File ------==//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file implements the pass that writes LLVM bytecode as data to a sparc
@@ -31,7 +31,7 @@ namespace {
typedef int int_type;
typedef std::streampos pos_type;
typedef std::streamoff off_type;
sparcasmbuf(std::ostream &On) : BaseStr(On) {}
virtual int_type overflow(int_type C) {
@@ -65,19 +65,19 @@ namespace {
const std::string &symName) {
// Prologue:
// Output a comment describing the object.
Out << "!" << comment << "\n";
Out << "!" << comment << "\n";
// Switch the current section to .rodata in the assembly output:
Out << "\t.section \".rodata\"\n\t.align 8\n";
Out << "\t.section \".rodata\"\n\t.align 8\n";
// Output a global symbol naming the object:
Out << "\t.global " << symName << "\n";
Out << "\t.type " << symName << ",#object\n";
Out << symName << ":\n";
Out << "\t.global " << symName << "\n";
Out << "\t.type " << symName << ",#object\n";
Out << symName << ":\n";
}
static void writeEpilogue (std::ostream &Out, const std::string &symName) {
// Epilogue:
// Output a local symbol marking the end of the object:
Out << ".end_" << symName << ":\n";
Out << ".end_" << symName << ":\n";
// Output size directive giving the size of the object:
Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
<< "\n";
@@ -90,7 +90,7 @@ namespace {
SparcV9BytecodeWriter(std::ostream &out) : Out(out) {}
const char *getPassName() const { return "Emit Bytecode to SparcV9 Assembly";}
virtual bool runOnModule(Module &M) {
// Write an object containing the bytecode to the SPARC assembly stream
writePrologue (Out, "LLVM BYTECODE OUTPUT", "LLVMBytecode");
@@ -101,7 +101,7 @@ namespace {
// Write an object containing its length as an integer to the
// SPARC assembly stream
writePrologue (Out, "LLVM BYTECODE LENGTH", "llvm_length");
Out <<"\t.word\t.end_LLVMBytecode-LLVMBytecode\n";
Out <<"\t.word\t.end_LLVMBytecode-LLVMBytecode\n";
writeEpilogue (Out, "llvm_length");
return false;
File diff suppressed because it is too large Load Diff
+93 -93
View File
@@ -1,10 +1,10 @@
//===- SchedGraph.cpp - Scheduling Graph Implementation -------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Scheduling graph based on SSA graph plus extra dependence edges capturing
@@ -31,7 +31,7 @@ namespace llvm {
// The following two types need to be classes, not typedefs, so we can use
// opaque declarations in SchedGraph.h
//
//
struct RefVec: public std::vector<std::pair<SchedGraphNode*, int> > {
typedef std::vector<std::pair<SchedGraphNode*,int> >::iterator iterator;
typedef
@@ -49,9 +49,9 @@ struct ValueToDefVecMap: public hash_map<const Value*, RefVec> {
};
//
//
// class SchedGraphNode
//
//
SchedGraphNode::SchedGraphNode(unsigned NID, MachineBasicBlock *mbb,
int indexInBB, const TargetMachine& Target)
@@ -82,9 +82,9 @@ SchedGraphNode::SchedGraphNode(unsigned NID, MachineBasicBlock *mbb,
SchedGraphNode::~SchedGraphNode() {
}
//
//
// class SchedGraph
//
//
SchedGraph::SchedGraph(MachineBasicBlock &mbb, const TargetMachine& target)
: MBB(mbb) {
buildGraph(target);
@@ -124,7 +124,7 @@ void SchedGraph::dump() const {
void SchedGraph::addDummyEdges() {
assert(graphRoot->getNumOutEdges() == 0);
for (const_iterator I=begin(); I != end(); ++I) {
SchedGraphNode* node = (*I).second;
assert(node != graphRoot && node != graphLeaf);
@@ -142,9 +142,9 @@ void SchedGraph::addCDEdges(const TerminatorInst* term,
const TargetMachine& target) {
const TargetInstrInfo& mii = *target.getInstrInfo();
MachineCodeForInstruction &termMvec = MachineCodeForInstruction::get(term);
// Find the first branch instr in the sequence of machine instrs for term
//
//
unsigned first = 0;
while (! mii.isBranch(termMvec[first]->getOpcode()) &&
! mii.isReturn(termMvec[first]->getOpcode()))
@@ -153,18 +153,18 @@ void SchedGraph::addCDEdges(const TerminatorInst* term,
"No branch instructions for terminator? Ok, but weird!");
if (first == termMvec.size())
return;
SchedGraphNode* firstBrNode = getGraphNodeForInstr(termMvec[first]);
// Add CD edges from each instruction in the sequence to the
// *last preceding* branch instr. in the sequence
// *last preceding* branch instr. in the sequence
// Use a latency of 0 because we only need to prevent out-of-order issue.
//
//
for (unsigned i = termMvec.size(); i > first+1; --i) {
SchedGraphNode* toNode = getGraphNodeForInstr(termMvec[i-1]);
assert(toNode && "No node for instr generated for branch/ret?");
for (unsigned j = i-1; j != 0; --j)
for (unsigned j = i-1; j != 0; --j)
if (mii.isBranch(termMvec[j-1]->getOpcode()) ||
mii.isReturn(termMvec[j-1]->getOpcode())) {
SchedGraphNode* brNode = getGraphNodeForInstr(termMvec[j-1]);
@@ -174,36 +174,36 @@ void SchedGraph::addCDEdges(const TerminatorInst* term,
break; // only one incoming edge is enough
}
}
// Add CD edges from each instruction preceding the first branch
// to the first branch. Use a latency of 0 as above.
//
//
for (unsigned i = first; i != 0; --i) {
SchedGraphNode* fromNode = getGraphNodeForInstr(termMvec[i-1]);
assert(fromNode && "No node for instr generated for branch?");
(void) new SchedGraphEdge(fromNode, firstBrNode, SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
}
// Now add CD edges to the first branch instruction in the sequence from
// all preceding instructions in the basic block. Use 0 latency again.
//
//
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
if (&*I == termMvec[first]) // reached the first branch
break;
SchedGraphNode* fromNode = getGraphNodeForInstr(I);
if (fromNode == NULL)
continue; // dummy instruction, e.g., PHI
(void) new SchedGraphEdge(fromNode, firstBrNode,
SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
// If we find any other machine instructions (other than due to
// the terminator) that also have delay slots, add an outgoing edge
// from the instruction to the instructions in the delay slots.
//
//
unsigned d = mii.getNumDelaySlots(I->getOpcode());
MachineBasicBlock::iterator J = I; ++J;
@@ -239,14 +239,14 @@ static const unsigned int SG_DepOrderArray[][3] = {
// instructions, where at least one is a store or a call.
// Use latency 1 just to ensure that memory operations are ordered;
// latency does not otherwise matter (true dependences enforce that).
//
//
void SchedGraph::addMemEdges(const std::vector<SchedGraphNode*>& memNodeVec,
const TargetMachine& target) {
const TargetInstrInfo& mii = *target.getInstrInfo();
// Instructions in memNodeVec are in execution order within the basic block,
// so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
//
//
for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++) {
MachineOpCode fromOpCode = memNodeVec[im]->getOpcode();
int fromType = (mii.isCall(fromOpCode)? SG_CALL_REF
@@ -257,28 +257,28 @@ void SchedGraph::addMemEdges(const std::vector<SchedGraphNode*>& memNodeVec,
int toType = (mii.isCall(toOpCode)? SG_CALL_REF
: (mii.isLoad(toOpCode)? SG_LOAD_REF
: SG_STORE_REF));
if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF)
(void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
SchedGraphEdge::MemoryDep,
SG_DepOrderArray[fromType][toType], 1);
}
}
}
}
// Add edges from/to CC reg instrs to/from call instrs.
// Essentially this prevents anything that sets or uses a CC reg from being
// reordered w.r.t. a call.
// Use a latency of 0 because we only need to prevent out-of-order issue,
// like with control dependences.
//
//
void SchedGraph::addCallDepEdges(const std::vector<SchedGraphNode*>& callDepNodeVec,
const TargetMachine& target) {
const TargetInstrInfo& mii = *target.getInstrInfo();
// Instructions in memNodeVec are in execution order within the basic block,
// so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
//
//
for (unsigned ic=0, NC=callDepNodeVec.size(); ic < NC; ic++)
if (mii.isCall(callDepNodeVec[ic]->getOpcode())) {
// Add SG_CALL_REF edges from all preds to this instruction.
@@ -286,26 +286,26 @@ void SchedGraph::addCallDepEdges(const std::vector<SchedGraphNode*>& callDepNode
(void) new SchedGraphEdge(callDepNodeVec[jc], callDepNodeVec[ic],
SchedGraphEdge::MachineRegister,
MachineIntRegsRID, 0);
// And do the same from this instruction to all successors.
for (unsigned jc=ic+1; jc < NC; jc++)
(void) new SchedGraphEdge(callDepNodeVec[ic], callDepNodeVec[jc],
SchedGraphEdge::MachineRegister,
MachineIntRegsRID, 0);
}
#ifdef CALL_DEP_NODE_VEC_CANNOT_WORK
// Find the call instruction nodes and put them in a vector.
std::vector<SchedGraphNode*> callNodeVec;
for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++)
if (mii.isCall(memNodeVec[im]->getOpcode()))
callNodeVec.push_back(memNodeVec[im]);
// Now walk the entire basic block, looking for CC instructions *and*
// call instructions, and keep track of the order of the instructions.
// Use the call node vec to quickly find earlier and later call nodes
// relative to the current CC instruction.
//
//
int lastCallNodeIdx = -1;
for (unsigned i=0, N=bbMvec.size(); i < N; i++)
if (mii.isCall(bbMvec[i]->getOpcode())) {
@@ -334,12 +334,12 @@ void SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
const TargetMachine& target) {
// This code assumes that two registers with different numbers are
// not aliased!
//
//
for (RegToRefVecMap::iterator I = regToRefVecMap.begin();
I != regToRefVecMap.end(); ++I) {
int regNum = (*I).first;
RefVec& regRefVec = (*I).second;
// regRefVec is ordered by control flow order in the basic block
for (unsigned i=0; i < regRefVec.size(); ++i) {
SchedGraphNode* node = regRefVec[i].first;
@@ -348,7 +348,7 @@ void SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
node->getMachineInstr()->getExplOrImplOperand(opNum);
bool isDef = mop.isDef() && !mop.isUse();
bool isDefAndUse = mop.isDef() && mop.isUse();
for (unsigned p=0; p < i; ++p) {
SchedGraphNode* prevNode = regRefVec[p].first;
if (prevNode != node) {
@@ -365,7 +365,7 @@ void SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
new SchedGraphEdge(prevNode, node, regNum,
SchedGraphEdge::AntiDep);
}
if (prevIsDef)
if (!isDef || isDefAndUse)
new SchedGraphEdge(prevNode, node, regNum,
@@ -380,7 +380,7 @@ void SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
// Adds dependences to/from refNode from/to all other defs
// in the basic block. refNode may be a use, a def, or both.
// We do not consider other uses because we are not building use-use deps.
//
//
void SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
const RefVec& defVec,
const Value* defValue,
@@ -392,7 +392,7 @@ void SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I) {
if ((*I).first == refNode)
continue; // Dont add any self-loops
if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB()) {
// (*).first is before refNode
if (refNodeIsDef && !refNodeIsUse)
@@ -420,9 +420,9 @@ void SchedGraph::addEdgesForInstruction(const MachineInstr& MI,
SchedGraphNode* node = getGraphNodeForInstr(&MI);
if (node == NULL)
return;
// Add edges for all operands of the machine instruction.
//
//
for (unsigned i = 0, numOps = MI.getNumOperands(); i != numOps; ++i) {
switch (MI.getOperand(i).getType()) {
case MachineOperand::MO_VirtualRegister:
@@ -435,26 +435,26 @@ void SchedGraph::addEdgesForInstruction(const MachineInstr& MI,
target);
}
break;
case MachineOperand::MO_MachineRegister:
break;
break;
case MachineOperand::MO_SignExtendedImmed:
case MachineOperand::MO_UnextendedImmed:
case MachineOperand::MO_PCRelativeDisp:
case MachineOperand::MO_ConstantPoolIndex:
break; // nothing to do for immediate fields
default:
assert(0 && "Unknown machine operand type in SchedGraph builder");
break;
}
}
// Add edges for values implicitly used by the machine instruction.
// Examples include function arguments to a Call instructions or the return
// value of a Ret instruction.
//
//
for (unsigned i=0, N=MI.getNumImplicitRefs(); i < N; ++i)
if (MI.getImplicitOp(i).isUse())
if (const Value* srcI = MI.getImplicitRef(i)) {
@@ -474,26 +474,26 @@ void SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap) {
const TargetInstrInfo& mii = *target.getInstrInfo();
MachineOpCode opCode = node->getOpcode();
if (mii.isCall(opCode) || mii.isCCInstr(opCode))
callDepNodeVec.push_back(node);
if (mii.isLoad(opCode) || mii.isStore(opCode) || mii.isCall(opCode))
memNodeVec.push_back(node);
// Collect the register references and value defs. for explicit operands
//
//
const MachineInstr& MI = *node->getMachineInstr();
for (int i=0, numOps = (int) MI.getNumOperands(); i < numOps; i++) {
const MachineOperand& mop = MI.getOperand(i);
// if this references a register other than the hardwired
// "zero" register, record the reference.
if (mop.hasAllocatedReg()) {
unsigned regNum = mop.getReg();
// If this is not a dummy zero register, record the reference in order
if (regNum != target.getRegInfo()->getZeroRegNum())
regToRefVecMap[mop.getReg()]
@@ -509,27 +509,27 @@ void SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
->isRegVolatile(regInClass))
callDepNodeVec.push_back(node);
}
continue; // nothing more to do
}
// ignore all other non-def operands
if (!MI.getOperand(i).isDef())
continue;
// We must be defining a value.
assert((mop.getType() == MachineOperand::MO_VirtualRegister ||
mop.getType() == MachineOperand::MO_CCRegister)
&& "Do not expect any other kind of operand to be defined!");
assert(mop.getVRegValue() != NULL && "Null value being defined?");
valueToDefVecMap[mop.getVRegValue()].push_back(std::make_pair(node, i));
valueToDefVecMap[mop.getVRegValue()].push_back(std::make_pair(node, i));
}
//
//
// Collect value defs. for implicit operands. They may have allocated
// physical registers also.
//
//
for (unsigned i=0, N = MI.getNumImplicitRefs(); i != N; ++i) {
const MachineOperand& mop = MI.getImplicitOp(i);
if (mop.hasAllocatedReg()) {
@@ -543,7 +543,7 @@ void SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
if (mop.isDef()) {
assert(MI.getImplicitRef(i) != NULL && "Null value being defined?");
valueToDefVecMap[MI.getImplicitRef(i)].push_back(
std::make_pair(node, -i));
std::make_pair(node, -i));
}
}
}
@@ -556,7 +556,7 @@ void SchedGraph::buildNodesForBB(const TargetMachine& target,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap) {
const TargetInstrInfo& mii = *target.getInstrInfo();
// Build graph nodes for each VM instruction and gather def/use info.
// Do both those together in a single pass over all machine instructions.
unsigned i = 0;
@@ -565,7 +565,7 @@ void SchedGraph::buildNodesForBB(const TargetMachine& target,
if (I->getOpcode() != V9::PHI) {
SchedGraphNode* node = new SchedGraphNode(getNumNodes(), &MBB, i, target);
noteGraphNodeForInstr(I, node);
// Remember all register references and value defs
findDefUseInfoAtInstr(target, node, memNodeVec, callDepNodeVec,
regToRefVecMap, valueToDefVecMap);
@@ -575,11 +575,11 @@ void SchedGraph::buildNodesForBB(const TargetMachine& target,
void SchedGraph::buildGraph(const TargetMachine& target) {
// Use this data structure to note all machine operands that compute
// ordinary LLVM values. These must be computed defs (i.e., instructions).
// ordinary LLVM values. These must be computed defs (i.e., instructions).
// Note that there may be multiple machine instructions that define
// each Value.
ValueToDefVecMap valueToDefVecMap;
// Use this data structure to note all memory instructions.
// We use this to add memory dependence edges without a second full walk.
std::vector<SchedGraphNode*> memNodeVec;
@@ -587,7 +587,7 @@ void SchedGraph::buildGraph(const TargetMachine& target) {
// Use this data structure to note all instructions that access physical
// registers that can be modified by a call (including call instructions)
std::vector<SchedGraphNode*> callDepNodeVec;
// Use this data structure to note any uses or definitions of
// machine registers so we can add edges for those later without
// extra passes over the nodes.
@@ -595,9 +595,9 @@ void SchedGraph::buildGraph(const TargetMachine& target) {
// ordered according to control-flow order. This only works for a
// single basic block, hence the assertion. Each reference is identified
// by the pair: <node, operand-number>.
//
//
RegToRefVecMap regToRefVecMap;
// Make a dummy root node. We'll add edges to the real roots later.
graphRoot = new SchedGraphNode(0, NULL, -1, target);
graphLeaf = new SchedGraphNode(1, NULL, -1, target);
@@ -611,7 +611,7 @@ void SchedGraph::buildGraph(const TargetMachine& target) {
buildNodesForBB(target, MBB, memNodeVec, callDepNodeVec,
regToRefVecMap, valueToDefVecMap);
//----------------------------------------------------------------
// Now add edges for the following (all are incoming edges except (4)):
// (1) operands of the machine instruction, including hidden operands
@@ -625,19 +625,19 @@ void SchedGraph::buildGraph(const TargetMachine& target) {
// 2-way conditional branches, multiple CD edges are needed
// (see addCDEdges for details).
// Also, note any uses or defs of machine registers.
//
//
//----------------------------------------------------------------
// First, add edges to the terminator instruction of the basic block.
this->addCDEdges(MBB.getBasicBlock()->getTerminator(), target);
// Then add memory dep edges: store->load, load->store, and store->store.
// Call instructions are treated as both load and store.
this->addMemEdges(memNodeVec, target);
// Then add edges between call instructions and CC set/use instructions
this->addCallDepEdges(callDepNodeVec, target);
// Then add incoming def-use (SSA) edges for each machine instruction.
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
addEdgesForInstruction(*I, valueToDefVecMap, target);
@@ -650,9 +650,9 @@ void SchedGraph::buildGraph(const TargetMachine& target) {
}
//
//
// class SchedGraphSet
//
//
SchedGraphSet::SchedGraphSet(const Function* _function,
const TargetMachine& target) :
function(_function) {
@@ -669,10 +669,10 @@ SchedGraphSet::~SchedGraphSet() {
void SchedGraphSet::dump() const {
std::cerr << "======== Sched graphs for function `" << function->getName()
<< "' ========\n\n";
for (const_iterator I=begin(); I != end(); ++I)
(*I)->dump();
std::cerr << "\n====== End graphs for function `" << function->getName()
<< "' ========\n\n";
}
@@ -689,28 +689,28 @@ void SchedGraphSet::buildGraphsForMethod(const Function *F,
void SchedGraphEdge::print(std::ostream &os) const {
os << "edge [" << src->getNodeId() << "] -> ["
<< sink->getNodeId() << "] : ";
switch(depType) {
case SchedGraphEdge::CtrlDep:
os<< "Control Dep";
os<< "Control Dep";
break;
case SchedGraphEdge::ValueDep:
os<< "Reg Value " << *val;
case SchedGraphEdge::ValueDep:
os<< "Reg Value " << *val;
break;
case SchedGraphEdge::MemoryDep:
os<< "Memory Dep";
os<< "Memory Dep";
break;
case SchedGraphEdge::MachineRegister:
case SchedGraphEdge::MachineRegister:
os<< "Reg " << machineRegNum;
break;
case SchedGraphEdge::MachineResource:
os<<"Resource "<< resourceId;
break;
default:
assert(0);
default:
assert(0);
break;
}
os << " : delay = " << minDelay << "\n";
}
@@ -718,7 +718,7 @@ void SchedGraphNode::print(std::ostream &os) const {
os << std::string(8, ' ')
<< "Node " << ID << " : "
<< "latency = " << latency << "\n" << std::string(12, ' ');
if (getMachineInstr() == NULL)
os << "(Dummy node)\n";
else {
@@ -726,7 +726,7 @@ void SchedGraphNode::print(std::ostream &os) const {
os << inEdges.size() << " Incoming Edges:\n";
for (unsigned i=0, N = inEdges.size(); i < N; i++)
os << std::string(16, ' ') << *inEdges[i];
os << std::string(12, ' ') << outEdges.size()
<< " Outgoing Edges:\n";
for (unsigned i=0, N= outEdges.size(); i < N; i++)
+31 -31
View File
@@ -1,19 +1,19 @@
//===-- SchedGraph.h - Scheduling Graph -------------------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is a scheduling graph based on SSA graph plus extra dependence edges
// capturing dependences due to machine resources (machine registers, CC
// registers, and any others).
//
//
// This graph tries to leverage the SSA graph as much as possible, but captures
// the extra dependences through a common interface.
//
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_SCHEDGRAPH_H
@@ -37,7 +37,7 @@ class SchedGraphNode : public SchedGraphNodeCommon {
const MachineInstr *MI;
SchedGraphNode(unsigned nodeId, MachineBasicBlock *mbb, int indexInBB,
SchedGraphNode(unsigned nodeId, MachineBasicBlock *mbb, int indexInBB,
const TargetMachine& Target);
~SchedGraphNode();
@@ -58,21 +58,21 @@ public:
class SchedGraph : public SchedGraphCommon {
MachineBasicBlock &MBB;
hash_map<const MachineInstr*, SchedGraphNode*> GraphMap;
public:
typedef hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator iterator;
typedef hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator const_iterator;
MachineBasicBlock& getBasicBlock() const{return MBB;}
const unsigned int getNumNodes() const { return GraphMap.size()+2; }
SchedGraphNode* getGraphNodeForInstr(const MachineInstr* MI) const {
const_iterator onePair = find(MI);
return (onePair != end())? onePair->second : NULL;
}
// Debugging support
void dump() const;
protected:
SchedGraph(MachineBasicBlock& mbb, const TargetMachine& TM);
~SchedGraph();
@@ -86,17 +86,17 @@ protected:
hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator end() const {
return GraphMap.end();
}
unsigned size() { return GraphMap.size(); }
iterator find(const MachineInstr *MI) const { return GraphMap.find(MI); }
SchedGraphNode *&operator[](const MachineInstr *MI) {
return GraphMap[MI];
}
private:
friend class SchedGraphSet; // give access to ctor
inline void noteGraphNodeForInstr (const MachineInstr* minstr,
SchedGraphNode* node) {
assert((*this)[minstr] == NULL);
@@ -107,39 +107,39 @@ private:
// Graph builder
//
void buildGraph(const TargetMachine& target);
void buildNodesForBB(const TargetMachine& target,MachineBasicBlock &MBB,
std::vector<SchedGraphNode*>& memNV,
std::vector<SchedGraphNode*>& callNV,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
void findDefUseInfoAtInstr(const TargetMachine& target, SchedGraphNode* node,
std::vector<SchedGraphNode*>& memNV,
std::vector<SchedGraphNode*>& callNV,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
void addEdgesForInstruction(const MachineInstr& minstr,
const ValueToDefVecMap& valueToDefVecMap,
const TargetMachine& target);
void addCDEdges(const TerminatorInst* term, const TargetMachine& target);
void addMemEdges(const std::vector<SchedGraphNode*>& memNod,
const TargetMachine& target);
void addCallCCEdges(const std::vector<SchedGraphNode*>& memNod,
MachineBasicBlock& bbMvec,
const TargetMachine& target);
void addCallDepEdges(const std::vector<SchedGraphNode*>& callNV,
const TargetMachine& target);
void addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
const TargetMachine& target);
void addEdgesForValue(SchedGraphNode* refNode, const RefVec& defVec,
const Value* defValue, bool refNodeIsDef,
bool refNodeIsDefAndUse,
@@ -161,12 +161,12 @@ class SchedGraphSet {
inline void addGraph(SchedGraph* graph) {
assert(graph != NULL);
Graphs.push_back(graph);
}
}
public:
SchedGraphSet(const Function *function, const TargetMachine& target);
~SchedGraphSet();
//iterators
typedef std::vector<SchedGraph*>::const_iterator iterator;
typedef std::vector<SchedGraph*>::const_iterator const_iterator;
@@ -181,7 +181,7 @@ public:
//
//
// sg_pred_iterator
// sg_pred_const_iterator
//
@@ -204,7 +204,7 @@ inline sg_pred_const_iterator pred_end(const SchedGraphNode *N) {
}
//
//
// sg_succ_iterator
// sg_succ_const_iterator
//
@@ -234,10 +234,10 @@ template <> struct GraphTraits<SchedGraph*> {
typedef sg_succ_iterator ChildIteratorType;
static inline NodeType *getEntryNode(SchedGraph *SG) { return (NodeType*)SG->getRoot(); }
static inline ChildIteratorType child_begin(NodeType *N) {
return succ_begin(N);
static inline ChildIteratorType child_begin(NodeType *N) {
return succ_begin(N);
}
static inline ChildIteratorType child_end(NodeType *N) {
static inline ChildIteratorType child_end(NodeType *N) {
return succ_end(N);
}
};
@@ -249,10 +249,10 @@ template <> struct GraphTraits<const SchedGraph*> {
static inline NodeType *getEntryNode(const SchedGraph *SG) {
return (NodeType*)SG->getRoot();
}
static inline ChildIteratorType child_begin(NodeType *N) {
return succ_begin(N);
static inline ChildIteratorType child_begin(NodeType *N) {
return succ_begin(N);
}
static inline ChildIteratorType child_end(NodeType *N) {
static inline ChildIteratorType child_end(NodeType *N) {
return succ_end(N);
}
};
@@ -1,10 +1,10 @@
//===- SchedGraphCommon.cpp - Scheduling Graphs Base Class- ---------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Scheduling graph base class that contains common information for SchedGraph
@@ -23,7 +23,7 @@ class SchedGraphCommon;
//
// class SchedGraphEdge
//
//
SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
SchedGraphNodeCommon* _sink,
SchedGraphEdgeDepType _depType,
@@ -31,7 +31,7 @@ SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
int _minDelay)
: src(_src), sink(_sink), depType(_depType), depOrderType(_depOrderType),
minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), val(NULL) {
iteDiff=0;
assert(src != sink && "Self-loop in scheduling graph!");
src->addOutEdge(this);
@@ -81,7 +81,7 @@ SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
void SchedGraphEdge::dump(int indent) const {
std::cerr << std::string(indent*2, ' ') << *this;
std::cerr << std::string(indent*2, ' ') << *this;
}
/*dtor*/
@@ -94,7 +94,7 @@ SchedGraphNodeCommon::~SchedGraphNodeCommon()
void SchedGraphNodeCommon::removeInEdge(const SchedGraphEdge* edge) {
assert(edge->getSink() == this);
for (iterator I = beginInEdges(); I != endInEdges(); ++I)
if ((*I) == edge) {
inEdges.erase(I);
@@ -104,7 +104,7 @@ void SchedGraphNodeCommon::removeInEdge(const SchedGraphEdge* edge) {
void SchedGraphNodeCommon::removeOutEdge(const SchedGraphEdge* edge) {
assert(edge->getSrc() == this);
for (iterator I = beginOutEdges(); I != endOutEdges(); ++I)
if ((*I) == edge) {
outEdges.erase(I);
@@ -113,7 +113,7 @@ void SchedGraphNodeCommon::removeOutEdge(const SchedGraphEdge* edge) {
}
void SchedGraphNodeCommon::dump(int indent) const {
std::cerr << std::string(indent*2, ' ') << *this;
std::cerr << std::string(indent*2, ' ') << *this;
}
//class SchedGraphCommon
@@ -124,7 +124,7 @@ SchedGraphCommon::~SchedGraphCommon() {
}
void SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node,
void SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node,
bool addDummyEdges) {
// Delete and disconnect all in-edges for the node
for (SchedGraphNodeCommon::iterator I = node->beginInEdges();
@@ -132,22 +132,22 @@ void SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node,
SchedGraphNodeCommon* srcNode = (*I)->getSrc();
srcNode->removeOutEdge(*I);
delete *I;
if (addDummyEdges && srcNode != getRoot() &&
srcNode->beginOutEdges() == srcNode->endOutEdges()) {
srcNode->beginOutEdges() == srcNode->endOutEdges()) {
// srcNode has no more out edges, so add an edge to dummy EXIT node
assert(node != getLeaf() && "Adding edge that was just removed?");
(void) new SchedGraphEdge(srcNode, getLeaf(),
SchedGraphEdge::CtrlDep,
SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
}
}
node->inEdges.clear();
}
void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node,
void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node,
bool addDummyEdges) {
// Delete and disconnect all out-edges for the node
for (SchedGraphNodeCommon::iterator I = node->beginOutEdges();
@@ -155,23 +155,23 @@ void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node,
SchedGraphNodeCommon* sinkNode = (*I)->getSink();
sinkNode->removeInEdge(*I);
delete *I;
if (addDummyEdges &&
sinkNode != getLeaf() &&
sinkNode->beginInEdges() == sinkNode->endInEdges()) {
//sinkNode has no more in edges, so add an edge from dummy ENTRY node
assert(node != getRoot() && "Adding edge that was just removed?");
(void) new SchedGraphEdge(getRoot(), sinkNode,
SchedGraphEdge::CtrlDep,
SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
}
}
node->outEdges.clear();
}
void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node,
void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node,
bool addDummyEdges) {
this->eraseIncomingEdges(node, addDummyEdges);
this->eraseOutgoingEdges(node, addDummyEdges);
@@ -1,12 +1,12 @@
//===-- SchedPriorities.h - Encapsulate scheduling heuristics -------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// Strategy:
// Priority ordering rules:
// (1) Max delay, which is the order of the heap S.candsAsHeap.
@@ -76,23 +76,23 @@ void
SchedPriorities::initializeReadyHeap(const SchedGraph* graph) {
const SchedGraphNode* graphRoot = (const SchedGraphNode*)graph->getRoot();
assert(graphRoot->getMachineInstr() == NULL && "Expect dummy root");
// Insert immediate successors of dummy root, which are the actual roots
sg_succ_const_iterator SEnd = succ_end(graphRoot);
for (sg_succ_const_iterator S = succ_begin(graphRoot); S != SEnd; ++S)
this->insertReady(*S);
#undef TEST_HEAP_CONVERSION
#ifdef TEST_HEAP_CONVERSION
std::cerr << "Before heap conversion:\n";
copy(candsAsHeap.begin(), candsAsHeap.end(),
ostream_iterator<NodeDelayPair*>(std::cerr,"\n"));
#endif
candsAsHeap.makeHeap();
nextToTry = candsAsHeap.begin();
#ifdef TEST_HEAP_CONVERSION
std::cerr << "After heap conversion:\n";
copy(candsAsHeap.begin(), candsAsHeap.end(),
@@ -107,7 +107,7 @@ SchedPriorities::insertReady(const SchedGraphNode* node) {
mcands.clear(); // ensure reset choices is called before any more choices
earliestReadyTime = std::min(earliestReadyTime,
getEarliestReadyTimeForNode(node));
if (SchedDebugLevel >= Sched_PrintSchedTrace) {
std::cerr << " Node " << node->getNodeId() << " will be ready in Cycle "
<< getEarliestReadyTimeForNode(node) << "; "
@@ -122,26 +122,26 @@ SchedPriorities::issuedReadyNodeAt(CycleCount_t curTime,
candsAsHeap.removeNode(node);
candsAsSet.erase(node);
mcands.clear(); // ensure reset choices is called before any more choices
if (earliestReadyTime == getEarliestReadyTimeForNode(node)) {
// earliestReadyTime may have been due to this node, so recompute it
earliestReadyTime = HUGE_LATENCY;
for (NodeHeap::const_iterator I=candsAsHeap.begin();
I != candsAsHeap.end(); ++I)
if (candsAsHeap.getNode(I)) {
earliestReadyTime =
std::min(earliestReadyTime,
earliestReadyTime =
std::min(earliestReadyTime,
getEarliestReadyTimeForNode(candsAsHeap.getNode(I)));
}
}
// Now update ready times for successors
for (SchedGraphNode::const_iterator E=node->beginOutEdges();
E != node->endOutEdges(); ++E) {
CycleCount_t& etime =
getEarliestReadyTimeForNodeRef((SchedGraphNode*)(*E)->getSink());
etime = std::max(etime, curTime + (*E)->getMinDelay());
}
}
}
@@ -182,7 +182,7 @@ SchedPriorities::chooseByRule3(std::vector<candIndex>& mcands) {
indexWithMaxUses = i;
}
}
return indexWithMaxUses;
return indexWithMaxUses;
}
const SchedGraphNode*
@@ -190,22 +190,22 @@ SchedPriorities::getNextHighest(const SchedulingManager& S,
CycleCount_t curTime) {
int nextIdx = -1;
const SchedGraphNode* nextChoice = NULL;
if (mcands.size() == 0)
findSetWithMaxDelay(mcands, S);
while (nextIdx < 0 && mcands.size() > 0) {
nextIdx = chooseByRule1(mcands); // rule 1
if (nextIdx == -1)
nextIdx = chooseByRule2(mcands); // rule 2
if (nextIdx == -1)
nextIdx = chooseByRule3(mcands); // rule 3
if (nextIdx == -1)
nextIdx = 0; // default to first choice by delays
// We have found the next best candidate. Check if it ready in
// the current cycle, and if it is feasible.
// If not, remove it from mcands and continue. Refill mcands if
@@ -220,7 +220,7 @@ SchedPriorities::getNextHighest(const SchedulingManager& S,
findSetWithMaxDelay(mcands, S);
}
}
if (nextIdx >= 0) {
mcands.erase(mcands.begin() + nextIdx);
return nextChoice;
@@ -241,9 +241,9 @@ SchedPriorities::findSetWithMaxDelay(std::vector<candIndex>& mcands,
for (; next != candsAsHeap.end()
&& candsAsHeap.getDelay(next) == maxDelay; ++next)
mcands.push_back(next);
nextToTry = next;
if (SchedDebugLevel >= Sched_PrintSchedTrace) {
std::cerr << " Cycle " << (long)getTime() << ": "
<< "Next highest delay = " << (long)maxDelay << " : "
@@ -260,17 +260,17 @@ bool
SchedPriorities::instructionHasLastUse(FunctionLiveVarInfo &LVI,
const SchedGraphNode* graphNode) {
const MachineInstr *MI = graphNode->getMachineInstr();
hash_map<const MachineInstr*, bool>::const_iterator
ui = lastUseMap.find(MI);
if (ui != lastUseMap.end())
return ui->second;
// else check if instruction is a last use and save it in the hash_map
bool hasLastUse = false;
const BasicBlock* bb = graphNode->getMachineBasicBlock().getBasicBlock();
const ValueSet &LVs = LVI.getLiveVarSetBeforeMInst(MI, bb);
for (MachineInstr::const_val_op_iterator OI = MI->begin(), OE = MI->end();
OI != OE; ++OI)
if (!LVs.count(*OI)) {
+30 -30
View File
@@ -1,12 +1,12 @@
//===-- SchedPriorities.h - Encapsulate scheduling heuristics --*- C++ -*--===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// Strategy:
// Priority ordering rules:
// (1) Max delay, which is the order of the heap S.candsAsHeap.
@@ -39,7 +39,7 @@ class FunctionLiveVarInfo;
enum SchedDebugLevel_t {
Sched_NoDebugInfo,
Sched_Disable,
Sched_PrintMachineCode,
Sched_PrintMachineCode,
Sched_PrintSchedTrace,
Sched_PrintSchedGraphs,
};
@@ -48,7 +48,7 @@ extern SchedDebugLevel_t SchedDebugLevel;
//---------------------------------------------------------------------------
// Function: instrIsFeasible
//
//
// Purpose:
// Used by the priority analysis to filter out instructions
// that are not feasible to issue in the current cycle.
@@ -78,26 +78,26 @@ class NodeHeap : public std::list<NodeDelayPair*> {
public:
typedef std::list<NodeDelayPair*>::iterator iterator;
typedef std::list<NodeDelayPair*>::const_iterator const_iterator;
public:
NodeHeap() : _size(0) {}
inline unsigned size() const { return _size; }
const SchedGraphNode* getNode (const_iterator i) const { return (*i)->node; }
CycleCount_t getDelay(const_iterator i) const { return (*i)->delay;}
inline void makeHeap() {
inline void makeHeap() {
// make_heap(begin(), end(), NDPLessThan);
}
inline iterator findNode(const SchedGraphNode* node) {
for (iterator I=begin(); I != end(); ++I)
if (getNode(I) == node)
return I;
return end();
}
inline void removeNode (const SchedGraphNode* node) {
iterator ndpPtr = findNode(node);
if (ndpPtr != end())
@@ -107,7 +107,7 @@ public:
--_size;
}
};
void insert(const SchedGraphNode* node, CycleCount_t delay) {
NodeDelayPair* ndp = new NodeDelayPair(node, delay);
if (_size == 0 || front()->delay < delay)
@@ -132,32 +132,32 @@ class SchedPriorities {
public:
SchedPriorities(const Function *F, const SchedGraph *G,
FunctionLiveVarInfo &LVI);
// This must be called before scheduling begins.
void initialize ();
CycleCount_t getTime () const { return curTime; }
CycleCount_t getEarliestReadyTime () const { return earliestReadyTime; }
unsigned getNumReady () const { return candsAsHeap.size(); }
bool nodeIsReady (const SchedGraphNode* node) const {
return (candsAsSet.find(node) != candsAsSet.end());
}
void issuedReadyNodeAt (CycleCount_t curTime,
const SchedGraphNode* node);
void insertReady (const SchedGraphNode* node);
void updateTime (CycleCount_t /*unused*/);
const SchedGraphNode* getNextHighest (const SchedulingManager& S,
CycleCount_t curTime);
// choose next highest priority instr
private:
typedef NodeHeap::iterator candIndex;
private:
CycleCount_t curTime;
const SchedGraph* graph;
@@ -173,21 +173,21 @@ private:
std::vector<candIndex> mcands; // holds pointers into cands
candIndex nextToTry; // next cand after the last
// one tried in this cycle
int chooseByRule1 (std::vector<candIndex>& mcands);
int chooseByRule2 (std::vector<candIndex>& mcands);
int chooseByRule3 (std::vector<candIndex>& mcands);
void findSetWithMaxDelay (std::vector<candIndex>& mcands,
const SchedulingManager& S);
void computeDelays (const SchedGraph* graph);
void initializeReadyHeap (const SchedGraph* graph);
bool instructionHasLastUse (FunctionLiveVarInfo& LVI,
const SchedGraphNode* graphNode);
// NOTE: The next two return references to the actual vector entries.
// Use the following two if you don't need to modify the value.
CycleCount_t& getNodeDelayRef (const SchedGraphNode* node) {
@@ -198,9 +198,9 @@ private:
assert(node->getNodeId() < earliestReadyTimeForNode.size());
return earliestReadyTimeForNode[node->getNodeId()];
}
CycleCount_t getNodeDelay (const SchedGraphNode* node) const {
return ((SchedPriorities*) this)->getNodeDelayRef(node);
return ((SchedPriorities*) this)->getNodeDelayRef(node);
}
CycleCount_t getEarliestReadyTimeForNode(const SchedGraphNode* node) const {
return ((SchedPriorities*) this)->getEarliestReadyTimeForNodeRef(node);
+3 -3
View File
@@ -1,10 +1,10 @@
//===-- InternalGlobalMapper.cpp - Mapping Info for Internal Globals ------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// InternalGlobalMapper is a pass that helps the runtime trace optimizer map
@@ -71,7 +71,7 @@ bool InternalGlobalMapper::runOnModule(Module &M) {
std::vector<Constant *> FieldValues;
FieldValues.push_back (ConstantUInt::get (Type::UIntTy, gvvector.size ()));
FieldValues.push_back (ConstantArray::get (ATy, gvvector));
// Add the constant struct to M as an external global symbol named
// "_llvm_internalGlobals".
new GlobalVariable (STy, true, GlobalValue::ExternalLinkage,
+27 -27
View File
@@ -1,10 +1,10 @@
//===-- BBLiveVar.cpp - Live Variable Analysis for a BasicBlock -----------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is a wrapper class for BasicBlock which is used by live var analysis.
@@ -43,7 +43,7 @@ void BBLiveVar::calcDefUseSets() {
for (MachineBasicBlock::const_reverse_iterator MII = MBB.rbegin(),
MIE = MBB.rend(); MII != MIE; ++MII) {
const MachineInstr *MI = &*MII;
if (DEBUG_LV >= LV_DEBUG_Verbose) {
std::cerr << " *Iterating over machine instr ";
MI->dump();
@@ -60,7 +60,7 @@ void BBLiveVar::calcDefUseSets() {
for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i)
if (MI->getImplicitOp(i).isDef())
addDef(MI->getImplicitRef(i));
// iterate over MI operands to find uses
for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end();
OpI != OpE; ++OpI) {
@@ -75,16 +75,16 @@ void BBLiveVar::calcDefUseSets() {
// instructions is untested. The previous code was broken and I
// fixed it, but it turned out to be unused as long as Phi
// elimination is performed during instruction selection.
//
//
// Put Phi operands in UseSet for the incoming edge, not node.
// They must not "hide" later defs, and must be handled specially
// during set propagation over the CFG.
if (MI->getOpcode() == V9::PHI) { // for a phi node
const Value *ArgVal = Op;
const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB
PredToEdgeInSetMap[PredBB].insert(ArgVal);
PredToEdgeInSetMap[PredBB].insert(ArgVal);
if (DEBUG_LV >= LV_DEBUG_Verbose)
std::cerr << " - phi operand " << RAV(ArgVal) << " came from BB "
<< RAV(PredBB) << "\n";
@@ -108,7 +108,7 @@ void BBLiveVar::calcDefUseSets() {
addUse(Op);
}
} // for all machine instructions
}
}
@@ -118,7 +118,7 @@ void BBLiveVar::calcDefUseSets() {
void BBLiveVar::addDef(const Value *Op) {
DefSet.insert(Op); // operand is a def - so add to def set
InSet.erase(Op); // this definition kills any later uses
InSetChanged = true;
InSetChanged = true;
if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << " +Def: " << RAV(Op) << "\n";
}
@@ -130,7 +130,7 @@ void BBLiveVar::addDef(const Value *Op) {
void BBLiveVar::addUse(const Value *Op) {
InSet.insert(Op); // An operand is a use - so add to use set
DefSet.erase(Op); // remove if there is a def below this use
InSetChanged = true;
InSetChanged = true;
if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << " Use: " << RAV(Op) << "\n";
}
@@ -138,16 +138,16 @@ void BBLiveVar::addUse(const Value *Op) {
//-----------------------------------------------------------------------------
// Applies the transfer function to a basic block to produce the InSet using
// the OutSet.
// the OutSet.
//-----------------------------------------------------------------------------
bool BBLiveVar::applyTransferFunc() {
// IMPORTANT: caller should check whether the OutSet changed
// IMPORTANT: caller should check whether the OutSet changed
// (else no point in calling)
ValueSet OutMinusDef = set_difference(OutSet, DefSet);
InSetChanged = set_union(InSet, OutMinusDef);
OutSetChanged = false; // no change to OutSet since transf func applied
return InSetChanged;
}
@@ -157,31 +157,31 @@ bool BBLiveVar::applyTransferFunc() {
// calculates Out set using In sets of the successors
//-----------------------------------------------------------------------------
bool BBLiveVar::setPropagate(ValueSet *OutSet, const ValueSet *InSet,
bool BBLiveVar::setPropagate(ValueSet *OutSet, const ValueSet *InSet,
const BasicBlock *PredBB) {
bool Changed = false;
// merge all members of InSet into OutSet of the predecessor
for (ValueSet::const_iterator InIt = InSet->begin(), InE = InSet->end();
InIt != InE; ++InIt)
if ((OutSet->insert(*InIt)).second)
Changed = true;
//
//
//**** WARNING: The following code for handling dummy PHI machine
// instructions is untested. See explanation above.
//
//
// then merge all members of the EdgeInSet for the predecessor into the OutSet
const ValueSet& EdgeInSet = PredToEdgeInSetMap[PredBB];
for (ValueSet::const_iterator InIt = EdgeInSet.begin(), InE = EdgeInSet.end();
InIt != InE; ++InIt)
if ((OutSet->insert(*InIt)).second)
Changed = true;
//
//
//****
return Changed;
}
}
//-----------------------------------------------------------------------------
@@ -190,25 +190,25 @@ bool BBLiveVar::setPropagate(ValueSet *OutSet, const ValueSet *InSet,
bool BBLiveVar::applyFlowFunc(hash_map<const BasicBlock*,
BBLiveVar*> &BBLiveVarInfo) {
// IMPORTANT: caller should check whether inset changed
// IMPORTANT: caller should check whether inset changed
// (else no point in calling)
// If this BB changed any OutSets of preds whose POID is lower, than we need
// another iteration...
//
bool needAnotherIt = false;
bool needAnotherIt = false;
for (pred_const_iterator PI = pred_begin(&BB), PE = pred_end(&BB);
PI != PE ; ++PI) {
BBLiveVar *PredLVBB = BBLiveVarInfo[*PI];
// do set union
if (setPropagate(&PredLVBB->OutSet, &InSet, *PI)) {
if (setPropagate(&PredLVBB->OutSet, &InSet, *PI)) {
PredLVBB->OutSetChanged = true;
// if the predec POID is lower than mine
if (PredLVBB->getPOId() <= POID)
needAnotherIt = true;
needAnotherIt = true;
}
} // for
+7 -7
View File
@@ -1,10 +1,10 @@
//===-- BBLiveVar.h - Live Variable Analysis for a BasicBlock ---*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is a BasicBlock annotation class that is used by live var analysis to
@@ -46,14 +46,14 @@ class BBLiveVar {
// coming in on that edge. such uses have to be
// treated differently from ordinary uses.
hash_map<const BasicBlock *, ValueSet> PredToEdgeInSetMap;
// method to propagate an InSet to OutSet of a predecessor
bool setPropagate(ValueSet *OutSetOfPred,
bool setPropagate(ValueSet *OutSetOfPred,
const ValueSet *InSetOfThisBB,
const BasicBlock *PredBB);
// To add an operand which is a def
void addDef(const Value *Op);
void addDef(const Value *Op);
// To add an operand which is a use
void addUse(const Value *Op);
@@ -63,14 +63,14 @@ public:
BBLiveVar(const BasicBlock &BB, const MachineBasicBlock &MBB, unsigned POID);
inline bool isInSetChanged() const { return InSetChanged; }
inline bool isInSetChanged() const { return InSetChanged; }
inline bool isOutSetChanged() const { return OutSetChanged; }
const MachineBasicBlock &getMachineBasicBlock() const { return MBB; }
inline unsigned getPOId() const { return POID; }
bool applyTransferFunc(); // calcultes the In in terms of Out
bool applyTransferFunc(); // calcultes the In in terms of Out
// calculates Out set using In sets of the predecessors
bool applyFlowFunc(hash_map<const BasicBlock*, BBLiveVar*> &BBLiveVarInfo);
@@ -1,10 +1,10 @@
//===-- FunctionLiveVarInfo.cpp - Live Variable Analysis for a Function ---===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is the interface to function level live variable information that is
@@ -79,7 +79,7 @@ bool FunctionLiveVarInfo::runOnFunction(Function &F) {
unsigned int iter=0;
while (doSingleBackwardPass(M, iter++))
; // Iterate until we are done.
if (DEBUG_LV) std::cerr << "Live Variable Analysis complete!\n";
return false;
}
@@ -99,7 +99,7 @@ void FunctionLiveVarInfo::constructBBs(const Function *F) {
MachineFunction &MF = MachineFunction::get(F);
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
const BasicBlock &BB = *I->getBasicBlock(); // get the current BB
const BasicBlock &BB = *I->getBasicBlock(); // get the current BB
if (DEBUG_LV) std::cerr << " For BB " << RAV(BB) << ":\n";
BBLiveVar *LVBB;
@@ -116,7 +116,7 @@ void FunctionLiveVarInfo::constructBBs(const Function *F) {
LVBB = new BBLiveVar(BB, *I, ++POId);
}
BBLiveVarInfo[&BB] = LVBB;
if (DEBUG_LV)
LVBB->printAllSets();
}
@@ -140,19 +140,19 @@ bool FunctionLiveVarInfo::doSingleBackwardPass(const Function *M,
if (DEBUG_LV) std::cerr << " For BB " << (*BBI)->getName() << ":\n";
// InSets are initialized to "GenSet". Recompute only if OutSet changed.
if(LVBB->isOutSetChanged())
if(LVBB->isOutSetChanged())
LVBB->applyTransferFunc(); // apply the Tran Func to calc InSet
// OutSets are initialized to EMPTY. Recompute on first iter or if InSet
// changed.
if (iter == 0 || LVBB->isInSetChanged()) // to calc Outsets of preds
NeedAnotherIteration |= LVBB->applyFlowFunc(BBLiveVarInfo);
if (DEBUG_LV) LVBB->printInOutSets();
}
// true if we need to reiterate over the CFG
return NeedAnotherIteration;
return NeedAnotherIteration;
}
@@ -188,10 +188,10 @@ void FunctionLiveVarInfo::releaseMemory() {
// Following functions will give the LiveVar info for any machine instr in
// a function. It should be called after a call to analyze().
//
// These functions calculate live var info for all the machine instrs in a
// BB when LVInfo for one inst is requested. Hence, this function is useful
// when live var info is required for many (or all) instructions in a basic
// block. Also, the arguments to this function does not require specific
// These functions calculate live var info for all the machine instrs in a
// BB when LVInfo for one inst is requested. Hence, this function is useful
// when live var info is required for many (or all) instructions in a basic
// block. Also, the arguments to this function does not require specific
// iterators.
//-----------------------------------------------------------------------------
@@ -215,12 +215,12 @@ FunctionLiveVarInfo::getLiveVarSetBeforeMInst(const MachineInstr *MI,
// Gives live variable information after a machine instruction
//-----------------------------------------------------------------------------
const ValueSet &
const ValueSet &
FunctionLiveVarInfo::getLiveVarSetAfterMInst(const MachineInstr *MI,
const BasicBlock *BB) {
ValueSet* &LVSet = MInst2LVSetAI[MI]; // ref. to map entry
if (LVSet == NULL && BB != NULL) { // if not found and BB provided
if (LVSet == NULL && BB != NULL) { // if not found and BB provided
calcLiveVarSetsForBB(BB); // calc LVSet for all instrs in BB
assert(LVSet != NULL);
}
@@ -230,7 +230,7 @@ FunctionLiveVarInfo::getLiveVarSetAfterMInst(const MachineInstr *MI,
// This function applies a machine instr to a live var set (accepts OutSet) and
// makes necessary changes to it (produces InSet). Note that two for loops are
// used to first kill all defs and then to add all uses. This is because there
// can be instructions like Val = Val + 1 since we allow multiple defs to a
// can be instructions like Val = Val + 1 since we allow multiple defs to a
// machine instruction operand.
//
static void applyTranferFuncForMInst(ValueSet &LVS, const MachineInstr *MInst) {
@@ -261,7 +261,7 @@ static void applyTranferFuncForMInst(ValueSet &LVS, const MachineInstr *MInst) {
}
//-----------------------------------------------------------------------------
// This method calculates the live variable information for all the
// This method calculates the live variable information for all the
// instructions in a basic block and enter the newly constructed live
// variable sets into a the caches (MInst2LVSetAI, MInst2LVSetBI)
//-----------------------------------------------------------------------------
@@ -276,15 +276,15 @@ void FunctionLiveVarInfo::calcLiveVarSetsForBB(const BasicBlock *BB) {
if (DEBUG_LV >= LV_DEBUG_Instr)
std::cerr << "\n======For BB " << BB->getName()
<< ": Live var sets for instructions======\n";
ValueSet *SetAI = &getOutSetOfBB(BB); // init SetAI with OutSet
ValueSet CurSet(*SetAI); // CurSet now contains OutSet
// iterate over all the machine instructions in BB
for (MachineBasicBlock::const_reverse_iterator MII = MIVec.rbegin(),
MIE = MIVec.rend(); MII != MIE; ++MII) {
MIE = MIVec.rend(); MII != MIE; ++MII) {
// MI is cur machine inst
const MachineInstr *MI = &*MII;
const MachineInstr *MI = &*MII;
MInst2LVSetAI[MI] = SetAI; // record in After Inst map
@@ -316,7 +316,7 @@ void FunctionLiveVarInfo::calcLiveVarSetsForBB(const BasicBlock *BB) {
}
// SetAI will be used in the next iteration
SetAI = NewSet;
SetAI = NewSet;
}
}
@@ -1,34 +1,34 @@
//===-- CodeGen/FunctionLiveVarInfo.h - LiveVar Analysis --------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This is the interface for live variable info of a function that is required
// This is the interface for live variable info of a function that is required
// by any other part of the compiler
//
// After the analysis, getInSetOfBB or getOutSetofBB can be called to get
// After the analysis, getInSetOfBB or getOutSetofBB can be called to get
// live var info of a BB.
//
// The live var set before an instruction can be obtained in 2 ways:
//
// 1. Use the method getLiveVarSetAfterInst(Instruction *) to get the LV Info
// 1. Use the method getLiveVarSetAfterInst(Instruction *) to get the LV Info
// just after an instruction. (also exists getLiveVarSetBeforeInst(..))
//
// This function caluclates the LV info for a BB only once and caches that
// info. If the cache does not contain the LV info of the instruction, it
// This function caluclates the LV info for a BB only once and caches that
// info. If the cache does not contain the LV info of the instruction, it
// calculates the LV info for the whole BB and caches them.
//
// Getting liveVar info this way uses more memory since, LV info should be
// Getting liveVar info this way uses more memory since, LV info should be
// cached. However, if you need LV info of nearly all the instructions of a
// BB, this is the best and simplest interfrace.
//
// 2. Use the OutSet and applyTranferFuncForInst(const Instruction *const Inst)
// declared in LiveVarSet and traverse the instructions of a basic block in
// reverse (using const_reverse_iterator in the BB class).
// 2. Use the OutSet and applyTranferFuncForInst(const Instruction *const Inst)
// declared in LiveVarSet and traverse the instructions of a basic block in
// reverse (using const_reverse_iterator in the BB class).
//
//===----------------------------------------------------------------------===//
@@ -47,7 +47,7 @@ class MachineInstr;
class FunctionLiveVarInfo : public FunctionPass {
// Machine Instr to LiveVarSet Map for providing LVset BEFORE each inst
// These sets are owned by this map and will be freed in releaseMemory().
hash_map<const MachineInstr *, ValueSet *> MInst2LVSetBI;
hash_map<const MachineInstr *, ValueSet *> MInst2LVSetBI;
// Machine Instr to LiveVarSet Map for providing LVset AFTER each inst.
// These sets are just pointers to sets in MInst2LVSetBI or BBLiveVar.
@@ -62,13 +62,13 @@ class FunctionLiveVarInfo : public FunctionPass {
// constructs BBLiveVars and init Def and In sets
void constructBBs(const Function *F);
// do one backward pass over the CFG
bool doSingleBackwardPass(const Function *F, unsigned int iter);
bool doSingleBackwardPass(const Function *F, unsigned int iter);
// calculates live var sets for instructions in a BB
void calcLiveVarSetsForBB(const BasicBlock *BB);
public:
// --------- Implement the FunctionPass interface ----------------------
+3 -3
View File
@@ -1,9 +1,9 @@
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
// FIXME: Eliminate this file.
@@ -13,7 +13,7 @@
namespace llvm {
std::ostream &operator<<(std::ostream &O, RAV V) { // func to print a Value
std::ostream &operator<<(std::ostream &O, RAV V) { // func to print a Value
const Value &v = V.V;
if (v.hasName())
return O << (void*)&v << "(" << v.getName() << ") ";
@@ -1,10 +1,10 @@
//===-- MachineCodeForInstruction.cpp -------------------------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Container for the sequence of MachineInstrs created for a single
@@ -13,7 +13,7 @@
// they can be deleted when they are no longer needed, and finally, it also
// holds some extra information for 'call' Instructions (using the
// CallArgsDescriptor object, which is also implemented in this file).
//
//
//===----------------------------------------------------------------------===//
#include "MachineCodeForInstruction.h"
@@ -46,11 +46,11 @@ void MachineCodeForInstruction::dropAllReferences() {
MachineCodeForInstruction::~MachineCodeForInstruction() {
// Let go of all uses in temp. instructions
dropAllReferences();
// Free the Value objects created to hold intermediate values
for (unsigned i=0, N=tempVec.size(); i < N; i++)
delete tempVec[i];
// do not free the MachineInstr objects allocated. they are managed
// by the ilist in MachineBasicBlock
@@ -76,7 +76,7 @@ CallArgsDescriptor::CallArgsDescriptor(CallInst* _callInstr,
// Enter this object in the MachineCodeForInstr object of the CallInst.
// This transfers ownership of this object.
MachineCodeForInstruction::get(callInstr).setCallArgsDescriptor(this);
MachineCodeForInstruction::get(callInstr).setCallArgsDescriptor(this);
}
CallInst *CallArgsDescriptor::getReturnValue() const {
@@ -90,7 +90,7 @@ CallInst *CallArgsDescriptor::getReturnValue() const {
/// the CallArgsDescriptor from the MachineCodeForInstruction object for the
/// CallInstr. This is roundabout but avoids adding a new map or annotation
/// just to keep track of CallArgsDescriptors.
///
///
CallArgsDescriptor *CallArgsDescriptor::get(const MachineInstr *MI) {
const Value *retAddrVal = 0;
if ((MI->getOperand (0).getType () == MachineOperand::MO_MachineRegister
@@ -110,7 +110,7 @@ CallArgsDescriptor *CallArgsDescriptor::get(const MachineInstr *MI) {
const CallInst* callInstr = cast<CallInst>(retAddrReg->getOperand(0));
CallArgsDescriptor* desc =
MachineCodeForInstruction::get(callInstr).getCallArgsDescriptor();
MachineCodeForInstruction::get(callInstr).getCallArgsDescriptor();
assert(desc->getCallInst()==callInstr && "Incorrect call args descriptor?");
return desc;
}
@@ -1,28 +1,28 @@
//===-- MachineCodeForInstruction.h -----------------------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// FIXME: This file is SparcV9 specific. Do not rely on this class for new
// FIXME: This file is SparcV9 specific. Do not rely on this class for new
// targets, it will go away in the future.
//
// Representation of the sequence of machine instructions created for a single
// VM instruction. Additionally records information about hidden and implicit
// values used by the machine instructions: about hidden values used by the
// machine instructions:
//
//
// "Temporary values" are intermediate values used in the machine instruction
// sequence, but not in the VM instruction Note that such values should be
// treated as pure SSA values with no interpretation of their operands (i.e., as
// a TmpInstruction object which actually represents such a value).
//
//
// (2) "Implicit uses" are values used in the VM instruction but not in
// the machine instruction sequence
//
//
//===----------------------------------------------------------------------===//
#ifndef MACHINECODE_FOR_INSTRUCTION_H
@@ -44,7 +44,7 @@ class CallArgsDescriptor;
public:
MachineCodeForInstruction() : callArgsDesc(NULL) {}
~MachineCodeForInstruction();
static MachineCodeForInstruction &get(const Instruction *I);
static void destroy(const Instruction *I);
@@ -71,7 +71,7 @@ public:
}
iterator erase(iterator where) { return Contents.erase(where); }
iterator erase(iterator s, iterator e) { return Contents.erase(s, e); }
// dropAllReferences() - This function drops all references within
// temporary (hidden) instructions created in implementing the original
@@ -82,7 +82,7 @@ public:
const std::vector<Value*> &getTempValues() const { return tempVec; }
std::vector<Value*> &getTempValues() { return tempVec; }
MachineCodeForInstruction &addTemp(Value *tmp) {
tempVec.push_back(tmp);
return *this;
+15 -15
View File
@@ -1,12 +1,12 @@
//===-- SparcV9FunctionInfo.cpp -------------------------------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This implements the SparcV9 specific MachineFunctionInfo class.
//
//===----------------------------------------------------------------------===//
@@ -25,7 +25,7 @@ ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
unsigned &maxOptionalNumArgs)
{
unsigned maxSize = 0;
for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
if (const CallInst *callInst = dyn_cast<CallInst>(I))
@@ -34,16 +34,16 @@ ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
int numExtra = numOperands-6;
if (numExtra <= 0)
continue;
unsigned sizeForThisCall = numExtra * 8;
if (maxSize < sizeForThisCall)
maxSize = sizeForThisCall;
if ((int)maxOptionalNumArgs < numExtra)
maxOptionalNumArgs = (unsigned) numExtra;
}
return maxSize;
}
@@ -55,7 +55,7 @@ ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
// This function is similar to the corresponding function in EmitAssembly.cpp
// but they are unrelated. This one does not align at more than a
// double-word boundary whereas that one might.
//
//
inline unsigned
SizeToAlignment(unsigned size, const TargetMachine& target)
{
@@ -108,9 +108,9 @@ int SparcV9FunctionInfo::allocateLocalVar(const Value* val,
assert(! automaticVarsAreaFrozen &&
"Size of auto vars area has been used to compute an offset so "
"no more automatic vars should be allocated!");
// Check if we've allocated a stack slot for this value already
//
//
hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
if (pair != offsets.end())
return pair->second;
@@ -128,19 +128,19 @@ SparcV9FunctionInfo::allocateSpilledValue(const Type* type)
assert(! spillsAreaFrozen &&
"Size of reg spills area has been used to compute an offset so "
"no more register spill slots should be allocated!");
unsigned size = MF.getTarget().getTargetData().getTypeSize(type);
unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
bool growUp;
int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp);
int offset = growUp? firstOffset + getRegSpillsSize()
: firstOffset - (getRegSpillsSize() + size);
int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
size += abs(aligned - offset); // include alignment padding in size
incrementRegSpillsSize(size); // update size of reg. spills area
return aligned;
+14 -14
View File
@@ -1,18 +1,18 @@
//===-- SparcV9FunctionInfo.h -----------------------------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This class keeps track of information about the stack frame and about the
// per-function constant pool.
//
// FIXME: This class is completely SparcV9 specific. Do not use it for future
// targets. This file will be eliminated in future versions of LLVM.
//
//
//===----------------------------------------------------------------------===//
#ifndef MACHINEFUNCTIONINFO_H
@@ -62,7 +62,7 @@ public:
//
// Accessors for global information about generated code for a method.
//
//
bool isCompiledAsLeafMethod() const { return compiledAsLeaf; }
unsigned getStaticStackSize() const { return staticStackSize; }
unsigned getAutomaticVarsSize() const { return automaticVarsSize; }
@@ -72,31 +72,31 @@ public:
const hash_set<const Constant*> &getConstantPoolValues() const {
return constantsForConstPool;
}
//
// Modifiers used during code generation
//
//
void initializeFrameLayout ();
void addToConstantPool (const Constant* constVal) {
constantsForConstPool.insert(constVal);
}
void markAsLeafMethod() { compiledAsLeaf = true; }
int computeOffsetforLocalVar (const Value* local,
unsigned& getPaddedSize,
unsigned sizeToUse = 0);
int allocateLocalVar (const Value* local,
unsigned sizeToUse = 0);
int allocateSpilledValue (const Type* type);
int pushTempValue (unsigned size);
void popAllTempValues ();
void freezeSpillsArea () { spillsAreaFrozen = true; }
void freezeSpillsArea () { spillsAreaFrozen = true; }
void freezeAutomaticVarsArea () { automaticVarsAreaFrozen=true; }
private:
void incrementAutomaticVarsSize(int incr) {
automaticVarsSize+= incr;
+15 -15
View File
@@ -1,14 +1,14 @@
//===-- MachineInstrAnnot.h -------------------------------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Annotations used to pass information between SparcV9 code generation phases.
//
//
//===----------------------------------------------------------------------===//
#ifndef MACHINEINSTRANNOT_H
@@ -28,29 +28,29 @@ class CallArgInfo {
static const unsigned char IntArgReg = 0x1;
static const unsigned char FPArgReg = 0x2;
static const unsigned char StackSlot = 0x4;
Value* argVal; // this argument
int argCopyReg; // register used for second copy of arg. when
// multiple copies must be passed in registers
unsigned char passingMethod; // flags recording passing methods
public:
// Constructors
CallArgInfo(Value* _argVal)
: argVal(_argVal), argCopyReg(SparcV9RegInfo::getInvalidRegNum()),
passingMethod(0x0) {}
CallArgInfo(const CallArgInfo& obj)
: argVal(obj.argVal), argCopyReg(obj.argCopyReg),
passingMethod(obj.passingMethod) {}
// Accessor methods
Value* getArgVal() { return argVal; }
int getArgCopy() { return argCopyReg; }
bool usesIntArgReg() { return (bool) (passingMethod & IntArgReg);}
bool usesFPArgReg() { return (bool) (passingMethod & FPArgReg); }
bool usesStackSlot() { return (bool) (passingMethod & StackSlot);}
bool usesIntArgReg() { return (bool) (passingMethod & IntArgReg);}
bool usesFPArgReg() { return (bool) (passingMethod & FPArgReg); }
bool usesStackSlot() { return (bool) (passingMethod & StackSlot);}
// Modifier methods
void replaceArgVal(Value* newVal) { argVal = newVal; }
void setUseIntArgReg() { passingMethod |= IntArgReg; }
@@ -64,15 +64,15 @@ class CallArgsDescriptor {
std::vector<CallArgInfo> argInfoVec; // Descriptor for each argument
CallInst* callInstr; // The call instruction == result value
Value* funcPtr; // Pointer for indirect calls
Value* funcPtr; // Pointer for indirect calls
TmpInstruction* retAddrReg; // Tmp value for return address reg.
bool isVarArgs; // Is this a varargs call?
bool noPrototype; // Is this a call with no prototype?
public:
CallArgsDescriptor(CallInst* _callInstr, TmpInstruction* _retAddrReg,
bool _isVarArgs, bool _noPrototype);
// Accessor methods to retrieve information about the call
// Note that operands are numbered 1..#CallArgs
unsigned int getNumArgs() const { return argInfoVec.size(); }
@@ -86,7 +86,7 @@ public:
bool hasNoPrototype() const { return noPrototype; }
// Mechanism to get the descriptor for a CALL MachineInstr.
//
//
static CallArgsDescriptor *get(const MachineInstr* MI);
};
+14 -14
View File
@@ -1,10 +1,10 @@
//===- MappingInfo.cpp - create LLVM info and output to .s file -----------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains a FunctionPass called MappingInfoAsmPrinter,
@@ -36,7 +36,7 @@
namespace llvm {
namespace {
class MappingInfoAsmPrinter : public FunctionPass {
class MappingInfoAsmPrinter : public FunctionPass {
std::ostream &Out;
public:
MappingInfoAsmPrinter(std::ostream &out) : Out(out){}
@@ -78,8 +78,8 @@ bool MappingInfoAsmPrinter::runOnFunction(Function &FI) {
// Now, write out the maps.
BBMIMap.dumpAssembly (Out);
return false;
}
return false;
}
/// writeNumber - Write out the number X as a sequence of .byte
/// directives to the current output stream Out. This method performs a
@@ -146,7 +146,7 @@ void MappingInfoAsmPrinter::buildBBMIMap(Function &FI, MappingInfo &Map) {
create_BB_to_MInumber_Key(FI, BBkey);
selectOutputMap (Map);
MachineFunction &MF = MachineFunction::get(&FI);
MachineFunction &MF = MachineFunction::get(&FI);
for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
BI != BE; ++BI, ++bb) {
MachineBasicBlock &miBB = *BI;
@@ -165,19 +165,19 @@ static void writePrologue (std::ostream &Out, const std::string &comment,
const std::string &symName) {
// Prologue:
// Output a comment describing the object.
Out << "!" << comment << "\n";
Out << "!" << comment << "\n";
// Switch the current section to .rodata in the assembly output:
Out << "\t.section \".rodata\"\n\t.align 8\n";
Out << "\t.section \".rodata\"\n\t.align 8\n";
// Output a global symbol naming the object:
Out << "\t.global " << symName << "\n";
Out << "\t.type " << symName << ",#object\n";
Out << symName << ":\n";
Out << "\t.global " << symName << "\n";
Out << "\t.type " << symName << ",#object\n";
Out << symName << ":\n";
}
static void writeEpilogue (std::ostream &Out, const std::string &symName) {
// Epilogue:
// Output a local symbol marking the end of the object:
Out << ".end_" << symName << ":\n";
Out << ".end_" << symName << ":\n";
// Output size directive giving the size of the object:
Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
<< "\n";
@@ -199,7 +199,7 @@ void MappingInfo::dumpAssembly (std::ostream &Out) {
///
bool MappingInfoAsmPrinter::doFinalization (Module &M) {
unsigned f;
writePrologue(Out, "FUNCTION TO BB MAP", "FunctionBB");
f=0;
for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
@@ -209,7 +209,7 @@ bool MappingInfoAsmPrinter::doFinalization (Module &M) {
++f;
}
writeEpilogue(Out, "FunctionBB");
return false;
}
+2 -2
View File
@@ -1,10 +1,10 @@
//===- lib/Target/SparcV9/MappingInfo.h -------------------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Data structures to support the Reoptimizer's Instruction-to-MachineInstr
@@ -6,10 +6,10 @@
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//
//
//
//
//
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "ModuloSched"
@@ -23,25 +23,25 @@ using namespace llvm;
///
namespace llvm {
FunctionPass *createDependenceAnalyzer() {
return new DependenceAnalyzer();
return new DependenceAnalyzer();
}
}
bool DependenceAnalyzer::runOnFunction(Function &F) {
AA = &getAnalysis<AliasAnalysis>();
TD = &getAnalysis<TargetData>();
return false;
}
static RegisterAnalysis<DependenceAnalyzer>X("depanalyzer", "Dependence Analyzer");
DependenceResult DependenceAnalyzer::getDependenceInfo(Instruction *inst1, Instruction *inst2) {
std::vector<Dependence> deps;
DEBUG(std::cerr << "Inst1: " << *inst1 << "\n");
DEBUG(std::cerr << "Inst2: " << *inst2 << "\n");
if(LoadInst *ldInst = dyn_cast<LoadInst>(inst1)) {
@@ -55,7 +55,7 @@ FunctionPass *createDependenceAnalyzer() {
if(AA->alias(ldOp, (unsigned)TD->getTypeSize(ldOp->getType()),
stOp,(unsigned)TD->getTypeSize(stOp->getType()))
!= AliasAnalysis::NoAlias) {
//Anti Dep
deps.push_back(Dependence(0, Dependence::AntiDep));
}
@@ -63,7 +63,7 @@ FunctionPass *createDependenceAnalyzer() {
}
else if(StoreInst *stInst = dyn_cast<StoreInst>(inst1)) {
if(LoadInst *ldInst = dyn_cast<LoadInst>(inst2)) {
//Get load mem ref
Value *ldOp = ldInst->getOperand(0);
@@ -75,7 +75,7 @@ FunctionPass *createDependenceAnalyzer() {
if(AA->alias(ldOp, (unsigned)TD->getTypeSize(ldOp->getType()),
stOp,(unsigned)TD->getTypeSize(stOp->getType()))
!= AliasAnalysis::NoAlias) {
//Anti Dep
deps.push_back(Dependence(0, Dependence::TrueDep));
}
@@ -88,17 +88,17 @@ FunctionPass *createDependenceAnalyzer() {
//Get store mem ref
Value *stOp2 = stInst2->getOperand(1);
if(AA->alias(stOp1, (unsigned)TD->getTypeSize(stOp1->getType()),
stOp2,(unsigned)TD->getTypeSize(stOp2->getType()))
!= AliasAnalysis::NoAlias) {
//Anti Dep
deps.push_back(Dependence(0, Dependence::OutputDep));
}
}
}
else
assert("Expected a load or a store\n");
@@ -6,8 +6,8 @@
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEPENDENCEANALYZER_H
@@ -24,22 +24,22 @@ namespace llvm {
//class to represent a dependence
struct Dependence {
enum DataDepType {
TrueDep, AntiDep, OutputDep, NonDateDep,
};
Dependence(int diff, DataDepType dep) : iteDiff(diff), depType(dep) {}
unsigned getIteDiff() { return iteDiff; }
unsigned getDepType() { return depType; }
private:
unsigned iteDiff;
unsigned depType;
};
struct DependenceResult {
std::vector<Dependence> dependences;
DependenceResult(const std::vector<Dependence> &d) : dependences(d) {}
@@ -49,12 +49,12 @@ namespace llvm {
class DependenceAnalyzer : public FunctionPass {
AliasAnalysis *AA;
TargetData *TD;
public:
DependenceAnalyzer() { AA = 0; TD = 0; }
virtual bool runOnFunction(Function &F);
virtual const char* getPassName() const { return "DependenceAnalyzer"; }
// getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AliasAnalysis>();
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
//
//
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "ModuloSched"
@@ -21,7 +21,7 @@ using namespace llvm;
//Returns a boolean indicating if the start cycle needs to be increased/decreased
bool MSSchedule::insert(MSchedGraphNode *node, int cycle) {
//First, check if the cycle has a spot free to start
if(schedule.find(cycle) != schedule.end()) {
//Check if we have a free issue slot at this cycle
@@ -48,7 +48,7 @@ bool MSSchedule::insert(MSchedGraphNode *node, int cycle) {
DEBUG(std::cerr << "All issue slots taken\n");
return true;
}
void MSSchedule::addToSchedule(int cycle, MSchedGraphNode *node) {
@@ -64,31 +64,31 @@ void MSSchedule::addToSchedule(int cycle, MSchedGraphNode *node) {
std::vector<MSchedGraphNode*> nodes;
for(std::map<unsigned, MSchedGraphNode*>::iterator I = indexMap.begin(), E = indexMap.end(); I != E; ++I)
nodes.push_back(I->second);
schedule[cycle] = nodes;
}
bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
//Get Resource usage for this instruction
const TargetSchedInfo *msi = node->getParent()->getTarget()->getSchedInfo();
int currentCycle = cycle;
bool success = true;
//Get resource usage for this instruction
InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
//Loop over resources in each cycle and increments their usage count
for(unsigned i=0; i < resources.size(); ++i) {
for(unsigned j=0; j < resources[i].size(); ++j) {
//Get Resource to check its availability
int resourceNum = resources[i][j];
DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
//Check if this resource is available for this cycle
std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(currentCycle);
@@ -100,7 +100,7 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
//Check if there are enough of this resource and if so, increase count and move on
if(resourceUse->second < CPUResource::getCPUResource(resourceNum)->maxNumUsers)
++resourceUse->second;
else {
DEBUG(std::cerr << "No resource num " << resourceNum << " available for cycle " << currentCycle << "\n");
success = false;
@@ -123,18 +123,18 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
if(!success)
break;
//Increase cycle
currentCycle++;
}
if(!success) {
int oldCycle = cycle;
DEBUG(std::cerr << "Backtrack\n");
//Get resource usage for this instruction
InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
//Loop over resources in each cycle and increments their usage count
for(unsigned i=0; i < resources.size(); ++i) {
if(oldCycle < currentCycle) {
@@ -158,7 +158,7 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
oldCycle++;
}
return false;
}
return true;
@@ -166,7 +166,7 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
}
bool MSSchedule::constructKernel(int II, std::vector<MSchedGraphNode*> &branches, std::map<const MachineInstr*, unsigned> &indVar) {
//Our schedule is allowed to have negative numbers, so lets calculate this offset
int offset = schedule.begin()->first;
if(offset > 0)
@@ -184,12 +184,12 @@ bool MSSchedule::constructKernel(int II, std::vector<MSchedGraphNode*> &branches
int maxSN = 0;
DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
for(int index = offset; index < (II+offset); ++index) {
int count = 0;
for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
if(schedule.count(i)) {
for(std::vector<MSchedGraphNode*>::iterator I = schedule[i].begin(),
for(std::vector<MSchedGraphNode*>::iterator I = schedule[i].begin(),
E = schedule[i].end(); I != E; ++I) {
//Check if its a branch
if((*I)->isBranch()) {
@@ -228,7 +228,7 @@ bool MSSchedule::constructKernel(int II, std::vector<MSchedGraphNode*> &branches
indVar.erase(N->second);
}
}
kernel.push_back(std::make_pair((MachineInstr*) I->first->getInst(), I->second));
}
@@ -256,7 +256,7 @@ bool MSSchedule::constructKernel(int II, std::vector<MSchedGraphNode*> &branches
void MSSchedule::print(std::ostream &os) const {
os << "Schedule:\n";
for(schedule_const_iterator I = schedule.begin(), E = schedule.end(); I != E; ++I) {
os << "Cycle: " << I->first << "\n";
for(std::vector<MSchedGraphNode*>::const_iterator node = I->second.begin(), nodeEnd = I->second.end(); node != nodeEnd; ++node)
@@ -268,4 +268,4 @@ void MSSchedule::print(std::ostream &os) const {
E = kernel.end(); I != E; ++I)
os << "Node: " << *(I->first) << " Stage: " << I->second << "\n";
}
@@ -23,7 +23,7 @@ namespace llvm {
class MSSchedule {
std::map<int, std::vector<MSchedGraphNode*> > schedule;
unsigned numIssue;
//Internal map to keep track of explicit resources
std::map<int, std::map<int, int> > resourceNumPerCycle;
@@ -49,7 +49,7 @@ namespace llvm {
bool constructKernel(int II, std::vector<MSchedGraphNode*> &branches, std::map<const MachineInstr*, unsigned> &indVar);
int getMaxStage() { return maxStage; }
//iterators
typedef std::map<int, std::vector<MSchedGraphNode*> >::iterator schedule_iterator;
typedef std::map<int, std::vector<MSchedGraphNode*> >::const_iterator schedule_const_iterator;
@@ -61,7 +61,7 @@ namespace llvm {
typedef std::vector<std::pair<MachineInstr*, int> >::const_iterator kernel_const_iterator;
kernel_iterator kernel_begin() { return kernel.begin(); }
kernel_iterator kernel_end() { return kernel.end(); }
};
}
@@ -10,7 +10,7 @@
// A graph class for dependencies. This graph only contains true, anti, and
// output data dependencies for a given MachineBasicBlock. Dependencies
// across iterations are also computed. Unless data dependence analysis
// is provided, a conservative approach of adding dependencies between all
// is provided, a conservative approach of adding dependencies between all
// loads and stores is taken.
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "ModuloSched"
@@ -31,9 +31,9 @@
using namespace llvm;
//MSchedGraphNode constructor
MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
MSchedGraph *graph, unsigned idx,
unsigned late, bool isBranch)
unsigned late, bool isBranch)
: Inst(inst), Parent(graph), index(idx), latency(late), isBranchInstr(isBranch) {
//Add to the graph
@@ -41,7 +41,7 @@ MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
}
//MSchedGraphNode copy constructor
MSchedGraphNode::MSchedGraphNode(const MSchedGraphNode &N)
MSchedGraphNode::MSchedGraphNode(const MSchedGraphNode &N)
: Predecessors(N.Predecessors), Successors(N.Successors) {
Inst = N.Inst;
@@ -54,7 +54,7 @@ MSchedGraphNode::MSchedGraphNode(const MSchedGraphNode &N)
//Print the node (instruction and latency)
void MSchedGraphNode::print(std::ostream &os) const {
os << "MSchedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n";
os << "MSchedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n";
}
@@ -62,7 +62,7 @@ void MSchedGraphNode::print(std::ostream &os) const {
MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) {
//Loop over all the successors of our predecessor
//return the edge the corresponds to this in edge
for (MSchedGraphNode::succ_iterator I = pred->succ_begin(),
for (MSchedGraphNode::succ_iterator I = pred->succ_begin(),
E = pred->succ_end(); I != E; ++I) {
if (*I == this)
return I.getEdge();
@@ -115,24 +115,24 @@ bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) {
//Add a node to the graph
void MSchedGraph::addNode(const MachineInstr *MI,
MSchedGraphNode *node) {
//Make sure node does not already exist
assert(GraphMap.find(MI) == GraphMap.end()
//Make sure node does not already exist
assert(GraphMap.find(MI) == GraphMap.end()
&& "New MSchedGraphNode already exists for this instruction");
GraphMap[MI] = node;
}
//Delete a node to the graph
void MSchedGraph::deleteNode(MSchedGraphNode *node) {
//Delete the edge to this node from all predecessors
while(node->pred_size() > 0) {
//DEBUG(std::cerr << "Delete edge from: " << **P << " to " << *node << "\n");
//DEBUG(std::cerr << "Delete edge from: " << **P << " to " << *node << "\n");
MSchedGraphNode *pred = *(node->pred_begin());
pred->deleteSuccessor(node);
}
//Remove this node from the graph
GraphMap.erase(node->getInst());
@@ -141,15 +141,15 @@ void MSchedGraph::deleteNode(MSchedGraphNode *node) {
//Create a graph for a machine block. The ignoreInstrs map is so that we ignore instructions
//associated to the index variable since this is a special case in Modulo Scheduling.
//We only want to deal with the body of the loop.
MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ,
std::map<const MachineInstr*, unsigned> &ignoreInstrs,
MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ,
std::map<const MachineInstr*, unsigned> &ignoreInstrs,
DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm
)
: BB(bb), Target(targ) {
//Make sure BB is not null,
//Make sure BB is not null,
assert(BB != NULL && "Basic Block is null");
//DEBUG(std::cerr << "Constructing graph for " << bb << "\n");
//Create nodes and edges for this BB
@@ -160,22 +160,22 @@ MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ,
}
//Copies the graph and keeps a map from old to new nodes
MSchedGraph::MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes)
MSchedGraph::MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes)
: BB(G.BB), Target(G.Target) {
std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew;
//Copy all nodes
for(MSchedGraph::const_iterator N = G.GraphMap.begin(), NE = G.GraphMap.end();
for(MSchedGraph::const_iterator N = G.GraphMap.begin(), NE = G.GraphMap.end();
N != NE; ++N) {
MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
oldToNew[&*(N->second)] = newNode;
newNodes[newNode] = &*(N->second);
GraphMap[&*(N->first)] = newNode;
}
//Loop over nodes and update edges to point to new nodes
for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end(); N != NE; ++N) {
//Get the node we are dealing with
MSchedGraphNode *node = &*(N->second);
@@ -185,13 +185,13 @@ MSchedGraph::MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSched
for(unsigned i = 0; i < node->pred_size(); ++i) {
node->setPredecessor(i, oldToNew[node->getPredecessor(i)]);
}
for(unsigned i = 0; i < node->succ_size(); ++i) {
MSchedGraphEdge *edge = node->getSuccessor(i);
MSchedGraphNode *oldDest = edge->getDest();
edge->setDest(oldToNew[oldDest]);
}
}
}
}
//Deconstructor, deletes all nodes in the graph
@@ -202,7 +202,7 @@ MSchedGraph::~MSchedGraph () {
//Experimental code to add edges from the branch to all nodes dependent upon it.
void hasPath(MSchedGraphNode *node, std::set<MSchedGraphNode*> &visited,
void hasPath(MSchedGraphNode *node, std::set<MSchedGraphNode*> &visited,
std::set<MSchedGraphNode*> &branches, MSchedGraphNode *startNode,
std::set<std::pair<MSchedGraphNode*,MSchedGraphNode*> > &newEdges ) {
@@ -214,7 +214,7 @@ void hasPath(MSchedGraphNode *node, std::set<MSchedGraphNode*> &visited,
MSchedGraphNode *dest = edge->getDest();
if(branches.count(dest))
newEdges.insert(std::make_pair(dest, startNode));
//only visit if we have not already
else if(!visited.count(dest)) {
if(edge->getIteDiff() == 0)
@@ -246,26 +246,26 @@ void MSchedGraph::addBranchEdges() {
//Spit out all edges we are going to add
unsigned min = GraphMap.size();
if(newEdges.size() == 1) {
((newEdges.begin())->first)->addOutEdge(((newEdges.begin())->second),
MSchedGraphEdge::BranchDep,
((newEdges.begin())->first)->addOutEdge(((newEdges.begin())->second),
MSchedGraphEdge::BranchDep,
MSchedGraphEdge::NonDataDep, 1);
}
else {
unsigned count = 0;
MSchedGraphNode *start;
MSchedGraphNode *end;
for(std::set<std::pair<MSchedGraphNode*, MSchedGraphNode*> >::iterator I = newEdges.begin(), E = newEdges.end(); I != E; ++I) {
DEBUG(std::cerr << "Branch Edge from: " << *(I->first) << " to " << *(I->second) << "\n");
// if(I->second->getIndex() <= min) {
start = I->first;
end = I->second;
//min = I->second->getIndex();
//}
start->addOutEdge(end,
MSchedGraphEdge::BranchDep,
start->addOutEdge(end,
MSchedGraphEdge::BranchDep,
MSchedGraphEdge::NonDataDep, 1);
}
}
@@ -276,7 +276,7 @@ void MSchedGraph::addBranchEdges() {
void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs,
DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) {
//Get Machine target information for calculating latency
const TargetInstrInfo *MTI = Target.getInstrInfo();
@@ -300,7 +300,7 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
//Get each instruction of machine basic block, get the delay
//using the op code, create a new node for it, and add to the
//graph.
MachineOpCode opCode = MI->getOpcode();
int delay;
@@ -313,12 +313,12 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
#endif
//Get delay
delay = MTI->maxLatency(opCode);
//Create new node for this machine instruction and add to the graph.
//Create only if not a nop
if(MTI->isNop(opCode))
continue;
//Sparc BE does not use PHI opcode, so assert on this case
assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
@@ -331,9 +331,9 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
//Node is created and added to the graph automatically
MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay, isBranch);
DEBUG(std::cerr << "Created Node: " << *node << "\n");
DEBUG(std::cerr << "Created Node: " << *node << "\n");
//Check OpCode to keep track of memory operations to add memory dependencies later.
//Check OpCode to keep track of memory operations to add memory dependencies later.
if(MTI->isLoad(opCode) || MTI->isStore(opCode))
memInstructions.push_back(node);
@@ -343,8 +343,8 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
for(unsigned i=0; i < MI->getNumOperands(); ++i) {
//Get Operand
const MachineOperand &mOp = MI->getOperand(i);
//Check if it has an allocated register
//Check if it has an allocated register
if(mOp.hasAllocatedReg()) {
int regNum = mOp.getReg();
@@ -354,8 +354,8 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
}
continue;
}
//Add virtual registers dependencies
//Check if any exist in the value map already and create dependencies
//between them.
@@ -369,19 +369,19 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
DEBUG(std::cerr << "Read Operation in a PHI node\n");
continue;
}
if (const Value* srcI = mOp.getVRegValue()) {
//Find value in the map
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
= valuetoNodeMap.find(srcI);
//If there is something in the map already, add edges from
//those instructions
//to this one we are processing
if(V != valuetoNodeMap.end()) {
addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
//Add to value map
V->second.push_back(std::make_pair(i,node));
}
@@ -390,7 +390,7 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
//Put into value map
valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
}
}
}
}
++index;
}
@@ -437,7 +437,7 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
if (const Value* srcI = mOp.getVRegValue()) {
//Find value in the map
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
= valuetoNodeMap.find(srcI);
//If there is something in the map already, add edges from
@@ -449,17 +449,17 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
}
}
}
}
}
}
//Add dependencies for Value*s
void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
MSchedGraphNode *destNode, bool nodeIsUse,
MSchedGraphNode *destNode, bool nodeIsUse,
bool nodeIsDef, std::vector<const MachineInstr*> &phiInstrs, int diff) {
for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(),
for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(),
E = NodesInMap.end(); I != E; ++I) {
//Get node in vectors machine operand that is the same value as node
MSchedGraphNode *srcNode = I->second;
MachineOperand mOp = srcNode->getInst()->getOperand(I->first);
@@ -472,23 +472,23 @@ void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
if(nodeIsDef) {
if(mOp.isUse()) {
DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=anti)\n");
srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
MSchedGraphEdge::AntiDep, diff);
}
if(mOp.isDef()) {
DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=output)\n");
srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
MSchedGraphEdge::OutputDep, diff);
}
}
if(nodeIsUse) {
if(mOp.isDef()) {
DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=true)\n");
srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
MSchedGraphEdge::TrueDep, diff);
}
}
}
}
}
//Add dependencies for machine registers across iterations
@@ -502,24 +502,24 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
//Get Vector of nodes that use this register
std::vector<OpIndexNodePair> Nodes = (*I).second;
//Loop over nodes and determine the dependence between the other
//nodes in the vector
for(unsigned i =0; i < Nodes.size(); ++i) {
//Get src node operator index that uses this machine register
int srcOpIndex = Nodes[i].first;
//Get the actual src Node
MSchedGraphNode *srcNode = Nodes[i].second;
//Get Operand
const MachineOperand &srcMOp = srcNode->getInst()->getOperand(srcOpIndex);
bool srcIsUseandDef = srcMOp.isDef() && srcMOp.isUse();
bool srcIsUse = srcMOp.isUse() && !srcMOp.isDef();
//Look at all instructions after this in execution order
for(unsigned j=i+1; j < Nodes.size(); ++j) {
@@ -529,11 +529,11 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
if(srcIsUse)
srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep);
else if(srcIsUseandDef) {
srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep);
srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::OutputDep);
}
@@ -547,9 +547,9 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::TrueDep);
}
}
//Look at all the instructions before this one since machine registers
//could live across iterations.
for(unsigned j = 0; j < i; ++j) {
@@ -559,11 +559,11 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
if(srcIsUse)
srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep, 1);
else if(srcIsUseandDef) {
srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep, 1);
srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::OutputDep, 1);
}
@@ -582,19 +582,19 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
}
}
}
}
//Add edges between all loads and stores
//Can be less strict with alias analysis and data dependence analysis.
void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, DependenceAnalyzer &DA,
void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) {
//Get Target machine instruction info
const TargetInstrInfo *TMI = Target.getInstrInfo();
//Loop over all memory instructions in the vector
//Knowing that they are in execution, add true, anti, and output dependencies
for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) {
@@ -603,12 +603,12 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Depe
//Get the machine opCode to determine type of memory instruction
MachineOpCode srcNodeOpCode = srcInst->getOpcode();
//All instructions after this one in execution order have an iteration delay of 0
for(unsigned destIndex = srcIndex + 1; destIndex < memInst.size(); ++destIndex) {
MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst();
DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
DEBUG(std::cerr << "Inst1: " << *machineTollvm[srcInst] << "\n");
DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
@@ -619,17 +619,17 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Depe
for(std::vector<Dependence>::iterator d = dr.dependences.begin(), de = dr.dependences.end();
d != de; ++d) {
//Add edge from load to store
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
d->getDepType(), d->getIteDiff());
}
}
//All instructions before the src in execution order have an iteration delay of 1
for(unsigned destIndex = 0; destIndex < srcIndex; ++destIndex) {
MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst();
bool malias = false;
@@ -652,14 +652,14 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Depe
malias = true;
//Only add the edge if we can't verify that they do not alias
/*if(AA.alias(mOp2.getVRegValue(),
/*if(AA.alias(mOp2.getVRegValue(),
(unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()),
mOp.getVRegValue(),
mOp.getVRegValue(),
(unsigned)TD.getTypeSize(mOp.getVRegValue()->getType()))
!= AliasAnalysis::NoAlias) {*/
if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
MSchedGraphEdge::AntiDep, 1);
//}
}
@@ -681,24 +681,24 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Depe
malias = true;
//Only add the edge if we can't verify that they do not alias
/*if(AA.alias(mOp2.getVRegValue(),
/*if(AA.alias(mOp2.getVRegValue(),
(unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()),
mOp.getVRegValue(),
mOp.getVRegValue(),
(unsigned)TD.getTypeSize(mOp.getVRegValue()->getType()))
!= AliasAnalysis::NoAlias) {*/
if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
MSchedGraphEdge::OutputDep, 1);
else
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep,
MSchedGraphEdge::TrueDep, 1);
//}
}
}
}
}
@@ -10,7 +10,7 @@
// A graph class for dependencies. This graph only contains true, anti, and
// output data dependencies for a given MachineBasicBlock. Dependencies
// across iterations are also computed. Unless data dependence analysis
// is provided, a conservative approach of adding dependencies between all
// is provided, a conservative approach of adding dependencies between all
// loads and stores is taken.
//===----------------------------------------------------------------------===//
@@ -27,7 +27,7 @@
#include <vector>
namespace llvm {
class MSchedGraph;
class MSchedGraphNode;
template<class IteratorType, class NodeType>
@@ -40,12 +40,12 @@ namespace llvm {
enum DataDepOrderType {
TrueDep, AntiDep, OutputDep, NonDataDep
};
enum MSchedGraphEdgeType {
MemoryDep, ValueDep, MachineRegister, BranchDep
};
//Get or set edge data
//Get or set edge data
MSchedGraphNode *getDest() const { return dest; }
unsigned getIteDiff() { return iteDiff; }
unsigned getDepOrderType() { return depOrderType; }
@@ -53,10 +53,10 @@ namespace llvm {
private:
friend class MSchedGraphNode;
MSchedGraphEdge(MSchedGraphNode *destination, MSchedGraphEdgeType type,
unsigned deptype, unsigned diff)
MSchedGraphEdge(MSchedGraphNode *destination, MSchedGraphEdgeType type,
unsigned deptype, unsigned diff)
: dest(destination), depType(type), depOrderType(deptype), iteDiff(diff) {}
MSchedGraphNode *dest;
MSchedGraphEdgeType depType;
unsigned depOrderType;
@@ -67,18 +67,18 @@ namespace llvm {
//corresponding latency. Each node also contains a list of its
//predecessors and sucessors.
class MSchedGraphNode {
const MachineInstr* Inst; //Machine Instruction
MSchedGraph* Parent; //Graph this node belongs to
unsigned index; //Index in BB
unsigned latency; //Latency of Instruction
bool isBranchInstr; //Is this node the branch instr or not
std::vector<MSchedGraphNode*> Predecessors; //Predecessor Nodes
std::vector<MSchedGraphEdge> Successors; //Successor edges
public:
MSchedGraphNode(const MachineInstr *inst, MSchedGraph *graph,
MSchedGraphNode(const MachineInstr *inst, MSchedGraph *graph,
unsigned index, unsigned late=0, bool isBranch=false);
MSchedGraphNode(const MSchedGraphNode &N);
@@ -92,7 +92,7 @@ namespace llvm {
typedef std::vector<MSchedGraphNode*>::const_iterator pred_const_iterator;
pred_const_iterator pred_begin() const { return Predecessors.begin(); }
pred_const_iterator pred_end() const { return Predecessors.end(); }
typedef MSchedGraphNodeIterator<std::vector<MSchedGraphEdge>::const_iterator,
const MSchedGraphNode> succ_const_iterator;
succ_const_iterator succ_begin() const;
@@ -108,15 +108,15 @@ namespace llvm {
void setPredecessor(unsigned index, MSchedGraphNode *dest) {
Predecessors[index] = dest;
}
MSchedGraphNode* getPredecessor(unsigned index) {
return Predecessors[index];
}
MSchedGraphEdge* getSuccessor(unsigned index) {
return &Successors[index];
}
void deleteSuccessor(MSchedGraphNode *node) {
for (unsigned i = 0; i != Successors.size(); ++i)
if (Successors[i].getDest() == node) {
@@ -127,8 +127,8 @@ namespace llvm {
}
}
void addOutEdge(MSchedGraphNode *destination,
MSchedGraphEdge::MSchedGraphEdgeType type,
void addOutEdge(MSchedGraphNode *destination,
MSchedGraphEdge::MSchedGraphEdgeType type,
unsigned deptype, unsigned diff=0) {
Successors.push_back(MSchedGraphEdge(destination, type, deptype,diff));
destination->Predecessors.push_back(this);
@@ -173,13 +173,13 @@ namespace llvm {
return I->getDest();
}
NodeType* operator->() const { return operator*(); }
MSchedGraphNodeIterator& operator++() { // Preincrement
++I;
return *this;
}
MSchedGraphNodeIterator operator++(int) { // Postincrement
MSchedGraphNodeIterator tmp = *this; ++*this; return tmp;
MSchedGraphNodeIterator tmp = *this; ++*this; return tmp;
}
MSchedGraphEdge &getEdge() {
@@ -204,7 +204,7 @@ namespace llvm {
}
// ostream << operator for MSGraphNode class
inline std::ostream &operator<<(std::ostream &os,
inline std::ostream &operator<<(std::ostream &os,
const MSchedGraphNode &node) {
node.print(os);
return os;
@@ -217,56 +217,56 @@ namespace llvm {
template <> struct GraphTraits<MSchedGraphNode*> {
typedef MSchedGraphNode NodeType;
typedef MSchedGraphNode::succ_iterator ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
return N->succ_begin();
static inline ChildIteratorType child_begin(NodeType *N) {
return N->succ_begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
static inline ChildIteratorType child_end(NodeType *N) {
return N->succ_end();
}
static NodeType *getEntryNode(NodeType* N) { return N; }
};
//Graph class to represent dependence graph
class MSchedGraph {
const MachineBasicBlock *BB; //Machine basic block
const TargetMachine &Target; //Target Machine
//Nodes
std::map<const MachineInstr*, MSchedGraphNode*> GraphMap;
//Add Nodes and Edges to this graph for our BB
typedef std::pair<int, MSchedGraphNode*> OpIndexNodePair;
void buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs, DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
void addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
void addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
MSchedGraphNode *node,
bool nodeIsUse, bool nodeIsDef, std::vector<const MachineInstr*> &phiInstrs, int diff=0);
void addMachRegEdges(std::map<int,
void addMachRegEdges(std::map<int,
std::vector<OpIndexNodePair> >& regNumtoNodeMap);
void addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
void addBranchEdges();
public:
MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ,
std::map<const MachineInstr*, unsigned> &ignoreInstrs,
MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ,
std::map<const MachineInstr*, unsigned> &ignoreInstrs,
DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
//Copy constructor with maps to link old nodes to new nodes
MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes);
//Deconstructor!
~MSchedGraph();
//Add or delete nodes from the Graph
void addNode(const MachineInstr* MI, MSchedGraphNode *node);
void deleteNode(MSchedGraphNode *node);
//iterators
//iterators
typedef std::map<const MachineInstr*, MSchedGraphNode*>::iterator iterator;
typedef std::map<const MachineInstr*, MSchedGraphNode*>::const_iterator const_iterator;
typedef std::map<const MachineInstr*, MSchedGraphNode*>::reverse_iterator reverse_iterator;
@@ -283,7 +283,7 @@ namespace llvm {
};
// Provide specializations of GraphTraits to be able to use graph
@@ -296,11 +296,11 @@ namespace llvm {
template <> struct GraphTraits<MSchedGraph*> {
typedef MSchedGraphNode NodeType;
typedef MSchedGraphNode::succ_iterator ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
return N->succ_begin();
static inline ChildIteratorType child_begin(NodeType *N) {
return N->succ_begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
static inline ChildIteratorType child_end(NodeType *N) {
return N->succ_end();
}
@@ -316,20 +316,20 @@ namespace llvm {
}
};
template <> struct GraphTraits<const MSchedGraph*> {
typedef const MSchedGraphNode NodeType;
typedef MSchedGraphNode::succ_const_iterator ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
return N->succ_begin();
static inline ChildIteratorType child_begin(NodeType *N) {
return N->succ_begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
static inline ChildIteratorType child_end(NodeType *N) {
return N->succ_end();
}
typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
static nodes_iterator nodes_begin(MSchedGraph *G) {
return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
@@ -338,15 +338,15 @@ namespace llvm {
return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
}
};
template <> struct GraphTraits<Inverse<MSchedGraph*> > {
typedef MSchedGraphNode NodeType;
typedef MSchedGraphNode::pred_iterator ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
static inline ChildIteratorType child_begin(NodeType *N) {
return N->pred_begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
static inline ChildIteratorType child_end(NodeType *N) {
return N->pred_end();
}
typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
@@ -360,21 +360,21 @@ namespace llvm {
return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
}
};
template <> struct GraphTraits<Inverse<const MSchedGraph*> > {
typedef const MSchedGraphNode NodeType;
typedef MSchedGraphNode::pred_const_iterator ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
static inline ChildIteratorType child_begin(NodeType *N) {
return N->pred_begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
static inline ChildIteratorType child_end(NodeType *N) {
return N->pred_end();
}
typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
static nodes_iterator nodes_begin(MSchedGraph *G) {
return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
File diff suppressed because it is too large Load Diff
@@ -6,8 +6,8 @@
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MODULOSCHEDULING_H
@@ -22,7 +22,7 @@
#include <set>
namespace llvm {
//Struct to contain ModuloScheduling Specific Information for each node
struct MSNodeAttributes {
@@ -31,9 +31,9 @@ namespace llvm {
int MOB;
int depth;
int height;
MSNodeAttributes(int asap=-1, int alap=-1, int mob=-1,
int d=-1, int h=-1) : ASAP(asap), ALAP(alap),
MOB(mob), depth(d),
MSNodeAttributes(int asap=-1, int alap=-1, int mob=-1,
int d=-1, int h=-1) : ASAP(asap), ALAP(alap),
MOB(mob), depth(d),
height(h) {}
};
@@ -55,19 +55,19 @@ namespace llvm {
//Map that holds node to node attribute information
std::map<MSchedGraphNode*, MSNodeAttributes> nodeToAttributesMap;
//Map to hold all reccurrences
std::set<std::pair<int, std::vector<MSchedGraphNode*> > > recurrenceList;
//Set of edges to ignore, stored as src node and index into vector of successors
std::set<std::pair<MSchedGraphNode*, unsigned> > edgesToIgnore;
//Vector containing the partial order
std::vector<std::set<MSchedGraphNode*> > partialOrder;
//Vector containing the final node order
std::vector<MSchedGraphNode*> FinalNodeOrder;
//Schedule table, key is the cycle number and the vector is resource, node pairs
MSSchedule schedule;
@@ -77,7 +77,7 @@ namespace llvm {
//Internal functions
bool CreateDefMap(MachineBasicBlock *BI);
bool MachineBBisValid(const MachineBasicBlock *BI);
bool assocIndVar(Instruction *I, std::set<Instruction*> &indVar,
bool assocIndVar(Instruction *I, std::set<Instruction*> &indVar,
std::vector<Instruction*> &stack, BasicBlock *BB);
int calculateResMII(const MachineBasicBlock *BI);
int calculateRecMII(MSchedGraph *graph, int MII);
@@ -93,59 +93,59 @@ namespace llvm {
int findMaxASAP();
void orderNodes();
void findAllReccurrences(MSchedGraphNode *node,
void findAllReccurrences(MSchedGraphNode *node,
std::vector<MSchedGraphNode*> &visitedNodes, int II);
void addReccurrence(std::vector<MSchedGraphNode*> &recurrence, int II, MSchedGraphNode*, MSchedGraphNode*);
void findAllCircuits(MSchedGraph *MSG, int II);
bool circuit(MSchedGraphNode *v, std::vector<MSchedGraphNode*> &stack,
std::set<MSchedGraphNode*> &blocked,
bool circuit(MSchedGraphNode *v, std::vector<MSchedGraphNode*> &stack,
std::set<MSchedGraphNode*> &blocked,
std::vector<MSchedGraphNode*> &SCC, MSchedGraphNode *s,
std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B, int II,
std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes);
void unblock(MSchedGraphNode *u, std::set<MSchedGraphNode*> &blocked,
std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B);
void searchPath(MSchedGraphNode *node,
void searchPath(MSchedGraphNode *node,
std::vector<MSchedGraphNode*> &path,
std::set<MSchedGraphNode*> &nodesToAdd);
void pathToRecc(MSchedGraphNode *node,
void pathToRecc(MSchedGraphNode *node,
std::vector<MSchedGraphNode*> &path,
std::set<MSchedGraphNode*> &poSet, std::set<MSchedGraphNode*> &lastNodes);
void computePartialOrder();
bool computeSchedule(const MachineBasicBlock *BB);
bool scheduleNode(MSchedGraphNode *node,
bool scheduleNode(MSchedGraphNode *node,
int start, int end);
void predIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult);
void succIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult);
void reconstructLoop(MachineBasicBlock*);
//void saveValue(const MachineInstr*, const std::set<Value*>&, std::vector<Value*>*);
void fixBranches(std::vector<MachineBasicBlock *> &prologues, std::vector<BasicBlock*> &llvm_prologues, MachineBasicBlock *machineBB, BasicBlock *llvmBB, std::vector<MachineBasicBlock *> &epilogues, std::vector<BasicBlock*> &llvm_epilogues, MachineBasicBlock*);
void fixBranches(std::vector<MachineBasicBlock *> &prologues, std::vector<BasicBlock*> &llvm_prologues, MachineBasicBlock *machineBB, BasicBlock *llvmBB, std::vector<MachineBasicBlock *> &epilogues, std::vector<BasicBlock*> &llvm_epilogues, MachineBasicBlock*);
void writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation);
void writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave,std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs);
void writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs);
void removePHIs(const MachineBasicBlock *origBB, std::vector<MachineBasicBlock *> &prologues, std::vector<MachineBasicBlock *> &epilogues, MachineBasicBlock *kernelBB, std::map<Value*, MachineBasicBlock*> &newValLocation);
void connectedComponentSet(MSchedGraphNode *node, std::set<MSchedGraphNode*> &ccSet, std::set<MSchedGraphNode*> &lastNodes);
public:
ModuloSchedulingPass(TargetMachine &targ) : target(targ) {}
virtual bool runOnFunction(Function &F);
virtual const char* getPassName() const { return "ModuloScheduling"; }
// getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DependenceAnalyzer>();
+5 -5
View File
@@ -1,10 +1,10 @@
//===-- AllocInfo.h - Store info about regalloc decisions -------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This header file contains the data structure used to save the state
@@ -35,7 +35,7 @@ struct AllocInfo {
AllocInfo (int Inst_, int Op_, AllocStateTy State_, int Place_) :
Instruction(Inst_), Operand(Op_), AllocState(State_), Placement(Place_) { }
/// AllocInfo constructor -- Default constructor creates an invalid AllocInfo
/// AllocInfo constructor -- Default constructor creates an invalid AllocInfo
/// (presumably to be replaced with something meaningful later).
///
AllocInfo () :
@@ -71,8 +71,8 @@ struct AllocInfo {
///
bool operator== (const AllocInfo &X) const {
return (X.AllocState == AllocState) && (X.Placement == Placement);
}
bool operator!= (const AllocInfo &X) const { return !(*this == X); }
}
bool operator!= (const AllocInfo &X) const { return !(*this == X); }
/// Returns a human-readable string representation of the AllocState member.
///
+7 -7
View File
@@ -1,15 +1,15 @@
//===-- IGNode.cpp --------------------------------------------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// This file implements an Interference graph node for coloring-based register
// allocation.
//
//
//===----------------------------------------------------------------------===//
#include "IGNode.h"
@@ -19,11 +19,11 @@
namespace llvm {
//-----------------------------------------------------------------------------
// Sets this IGNode on stack and reduce the degree of neighbors
// Sets this IGNode on stack and reduce the degree of neighbors
//-----------------------------------------------------------------------------
void IGNode::pushOnStack() {
OnStack = true;
OnStack = true;
int neighs = AdjList.size();
if (neighs < 0) {
@@ -34,7 +34,7 @@ void IGNode::pushOnStack() {
for (int i=0; i < neighs; i++)
AdjList[i]->decCurDegree();
}
//-----------------------------------------------------------------------------
// Deletes an adjacency node. IGNodes are deleted when coalescing merges
// two IGNodes together.
+11 -11
View File
@@ -1,16 +1,16 @@
//===-- IGNode.h - Represent a node in an interference graph ----*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file represents a node in an interference graph.
// This file represents a node in an interference graph.
//
// For efficiency, the AdjList is updated only once - ie. we can add but not
// remove nodes from AdjList.
// remove nodes from AdjList.
//
// The removal of nodes from IG is simulated by decrementing the CurDegree.
// If this node is put on stack (that is removed from IG), the CurDegree of all
@@ -44,15 +44,15 @@ class RegClass;
//----------------------------------------------------------------------------
class IGNode {
const unsigned Index; // index within IGNodeList
const unsigned Index; // index within IGNodeList
bool OnStack; // this has been pushed on to stack for coloring
std::vector<IGNode *> AdjList;// adjacency list for this live range
int CurDegree;
int CurDegree;
//
// set by InterferenceGraph::setCurDegreeOfIGNodes() after calculating
// all adjacency lists.
// Decremented when a neighbor is pushed on to the stack.
// Decremented when a neighbor is pushed on to the stack.
// After that, never incremented/set again nor used.
LiveRange *const ParentLR;
@@ -68,15 +68,15 @@ public:
// adjLists must be updated only once. However, the CurDegree can be changed
//
inline void addAdjIGNode(IGNode *AdjNode) { AdjList.push_back(AdjNode); }
inline void addAdjIGNode(IGNode *AdjNode) { AdjList.push_back(AdjNode); }
inline IGNode *getAdjIGNode(unsigned ind) const
inline IGNode *getAdjIGNode(unsigned ind) const
{ assert ( ind < AdjList.size()); return AdjList[ind]; }
// delete a node in AdjList - node must be in the list
// should not be called often
//
void delAdjIGNode(const IGNode *Node);
void delAdjIGNode(const IGNode *Node);
inline unsigned getNumOfNeighbors() const { return AdjList.size(); }
@@ -87,7 +87,7 @@ public:
// remove form IG and pushes on to stack (reduce the degree of neighbors)
//
void pushOnStack();
void pushOnStack();
// CurDegree is the effective number of neighbors when neighbors are
// pushed on to the stack during the coloring phase. Must be called
@@ -1,14 +1,14 @@
//===-- InterferenceGraph.cpp ---------------------------------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// Interference graph for coloring-based register allocation for LLVM.
//
//
//===----------------------------------------------------------------------===//
#include "IGNode.h"
@@ -28,12 +28,12 @@ inline static void assertIGNode(const InterferenceGraph *IG,
//-----------------------------------------------------------------------------
// Constructor: Records the RegClass and initalizes IGNodeList.
// The matrix is NOT yet created by the constructor. Call createGraph()
// The matrix is NOT yet created by the constructor. Call createGraph()
// to create it after adding all IGNodes to the IGNodeList.
//-----------------------------------------------------------------------------
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC) {
IG = NULL;
Size = 0;
IG = NULL;
Size = 0;
if( DEBUG_RA >= RA_DEBUG_Interference)
std::cerr << "Interference graph created!\n";
}
@@ -58,15 +58,15 @@ InterferenceGraph:: ~InterferenceGraph() {
// Creates (dynamically allocates) the bit matrix necessary to hold the
// interference graph.
//-----------------------------------------------------------------------------
void InterferenceGraph::createGraph()
{
void InterferenceGraph::createGraph()
{
Size = IGNodeList.size();
IG = new char*[Size];
IG = new char*[Size];
for( unsigned int r=0; r < Size; ++r)
IG[r] = new char[Size];
// init IG matrix
for(unsigned int i=0; i < Size; i++)
for(unsigned int i=0; i < Size; i++)
for(unsigned int j=0; j < Size; j++)
IG[i][j] = 0;
}
@@ -89,27 +89,27 @@ void InterferenceGraph::addLRToIG(LiveRange *const LR)
//-----------------------------------------------------------------------------
void InterferenceGraph::setInterference(const LiveRange *const LR1,
const LiveRange *const LR2 ) {
assert(LR1 != LR2);
assert(LR1 != LR2);
IGNode *IGNode1 = LR1->getUserIGNode();
IGNode *IGNode2 = LR2->getUserIGNode();
assertIGNode(this, IGNode1);
assertIGNode(this, IGNode1);
assertIGNode(this, IGNode2);
unsigned row = IGNode1->getIndex();
unsigned col = IGNode2->getIndex();
char *val;
if( DEBUG_RA >= RA_DEBUG_Interference)
std::cerr << "setting intf for: [" << row << "][" << col << "]\n";
if( DEBUG_RA >= RA_DEBUG_Interference)
std::cerr << "setting intf for: [" << row << "][" << col << "]\n";
( row > col) ? val = &IG[row][col]: val = &IG[col][row];
( row > col) ? val = &IG[row][col]: val = &IG[col][row];
if( ! (*val) ) { // if this interf is not previously set
*val = 1; // add edges between nodes
IGNode1->addAdjIGNode( IGNode2 );
*val = 1; // add edges between nodes
IGNode1->addAdjIGNode( IGNode2 );
IGNode2->addAdjIGNode( IGNode1 );
}
@@ -122,17 +122,17 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
const LiveRange *const LR2) const {
assert(LR1 != LR2);
assertIGNode(this, LR1->getUserIGNode());
assertIGNode(this, LR1->getUserIGNode());
assertIGNode(this, LR2->getUserIGNode());
const unsigned int row = LR1->getUserIGNode()->getIndex();
const unsigned int col = LR2->getUserIGNode()->getIndex();
char ret;
char ret;
if (row > col)
ret = IG[row][col];
else
ret = IG[col][row];
else
ret = IG[col][row];
return ret;
}
@@ -141,11 +141,11 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
//----------------------------------------------------------------------------
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
// Then the IGNode2L will be deleted. Necessary for coalescing.
// IMPORTANT: The live ranges are NOT merged by this method. Use
// IMPORTANT: The live ranges are NOT merged by this method. Use
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
//----------------------------------------------------------------------------
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
LiveRange *LR2) {
assert( LR1 != LR2); // cannot merge the same live range
@@ -165,31 +165,31 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
// for all neighs of SrcNode
for(unsigned i=0; i < SrcDegree; i++) {
IGNode *NeighNode = SrcNode->getAdjIGNode(i);
for(unsigned i=0; i < SrcDegree; i++) {
IGNode *NeighNode = SrcNode->getAdjIGNode(i);
LiveRange *const LROfNeigh = NeighNode->getParentLR();
// delete edge between src and neigh - even neigh == dest
NeighNode->delAdjIGNode(SrcNode);
NeighNode->delAdjIGNode(SrcNode);
// set the matrix posn to 0 betn src and neigh - even neigh == dest
const unsigned NInd = NeighNode->getIndex();
( SrcInd > NInd) ? (IG[SrcInd][NInd]=0) : (IG[NInd][SrcInd]=0) ;
( SrcInd > NInd) ? (IG[SrcInd][NInd]=0) : (IG[NInd][SrcInd]=0) ;
if( LR1 != LROfNeigh) { // if the neigh != dest
if( LR1 != LROfNeigh) { // if the neigh != dest
// add edge betwn Dest and Neigh - if there is no current edge
setInterference(LR1, LROfNeigh );
setInterference(LR1, LROfNeigh );
}
}
IGNodeList[ SrcInd ] = NULL;
// SrcNode is no longer necessary - LR2 must be deleted by the caller
delete( SrcNode );
delete( SrcNode );
}
@@ -216,10 +216,10 @@ void InterferenceGraph::setCurDegreeOfIGNodes()
//--------------------- debugging (Printing) methods -----------------------
//----------------------------------------------------------------------------
// Print the IGnodes
// Print the IGnodes
//----------------------------------------------------------------------------
void InterferenceGraph::printIG() const {
for(unsigned i=0; i < Size; i++) {
for(unsigned i=0; i < Size; i++) {
const IGNode *const Node = IGNodeList[i];
if(Node) {
std::cerr << " [" << i << "] ";
+10 -10
View File
@@ -1,10 +1,10 @@
//===-- InterferenceGraph.h - Interference graph for register coloring -*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
/* Title: InterferenceGraph.h -*- C++ -*-
@@ -12,17 +12,17 @@
Date: July 20, 01
Purpose: Interference Graph used for register coloring.
Notes:
Adj Info is stored in the lower trangular matrix (i.e., row > col )
Notes:
Adj Info is stored in the lower trangular matrix (i.e., row > col )
This class must be used in the following way:
* Construct class
* call addLRToIG as many times to add ALL LRs to this IG
* call createGraph to create the actual matrix
* Then setInterference, getInterference, mergeIGNodesOfLRs can be
* Then setInterference, getInterference, mergeIGNodesOfLRs can be
called as desired to modify the graph.
* Once the modifications to the graph are over, call
* Once the modifications to the graph are over, call
setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring.
*/
@@ -42,9 +42,9 @@ class InterferenceGraph {
unsigned int Size; // size of a side of the IG
RegClass *const RegCl; // RegCl contains this IG
std::vector<IGNode *> IGNodeList; // a list of all IGNodes in a reg class
public:
// the matrix is not yet created by the constructor. Call createGraph()
// the matrix is not yet created by the constructor. Call createGraph()
// to create it after adding all IGNodes to the IGNodeList
InterferenceGraph(RegClass *RC);
~InterferenceGraph();
@@ -61,8 +61,8 @@ class InterferenceGraph {
void mergeIGNodesOfLRs(const LiveRange *LR1, LiveRange *LR2);
std::vector<IGNode *> &getIGNodeList() { return IGNodeList; }
const std::vector<IGNode *> &getIGNodeList() const { return IGNodeList; }
std::vector<IGNode *> &getIGNodeList() { return IGNodeList; }
const std::vector<IGNode *> &getIGNodeList() const { return IGNodeList; }
void setCurDegreeOfIGNodes();
+12 -12
View File
@@ -1,10 +1,10 @@
//===-- LiveRange.h - Store info about a live range -------------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// Implements a live range using a SetVector of Value *s. We keep only
@@ -34,7 +34,7 @@ private:
ValueContainerType MyValues; // Values in this LiveRange
RegClass *MyRegClass; // register class (e.g., int, FP) for this LR
/// doesSpanAcrossCalls - Does this live range span across calls?
/// doesSpanAcrossCalls - Does this live range span across calls?
/// This information is used by graph coloring algo to avoid allocating
/// volatile colors to live ranges that span across calls (since they have to
/// be saved/restored)
@@ -56,7 +56,7 @@ private:
/// this live range is not available before graph coloring (e.g., it
/// can be allocated to another live range which interferes with
/// this)
///
///
bool CanUseSuggestedCol;
/// SpilledStackOffsetFromFP - If this LR is spilled, its stack
@@ -83,7 +83,7 @@ public:
void insert(iterator b, iterator e) { MyValues.insert (b, e); }
LiveRange() {
Color = SuggestedColor = -1; // not yet colored
Color = SuggestedColor = -1; // not yet colored
mustSpill = false;
MyRegClass = 0;
UserIGNode = 0;
@@ -99,21 +99,21 @@ public:
unsigned getRegClassID() const;
bool hasColor() const { return Color != -1; }
unsigned getColor() const { assert(Color != -1); return (unsigned)Color; }
void setColor(unsigned Col) { Color = (int)Col; }
inline void setCallInterference() {
inline void setCallInterference() {
doesSpanAcrossCalls = 1;
}
inline void clearCallInterference() {
inline void clearCallInterference() {
doesSpanAcrossCalls = 0;
}
inline bool isCallInterference() const {
return doesSpanAcrossCalls == 1;
}
inline bool isCallInterference() const {
return doesSpanAcrossCalls == 1;
}
inline void markForSpill() { mustSpill = true; }
@@ -150,7 +150,7 @@ public:
inline const Type *getType() const {
return (*begin())->getType(); // set's don't have a front
}
inline void setSuggestedColor(int Col) {
if (SuggestedColor == -1)
SuggestedColor = Col;
+40 -40
View File
@@ -1,14 +1,14 @@
//===-- LiveRangeInfo.cpp -------------------------------------------------===//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
//
// Live range construction for coloring-based register allocation for LLVM.
//
//
//===----------------------------------------------------------------------===//
#include "IGNode.h"
@@ -35,8 +35,8 @@ LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm,
LiveRangeInfo::~LiveRangeInfo() {
for (LiveRangeMapType::iterator MI = LiveRangeMap.begin();
MI != LiveRangeMap.end(); ++MI) {
for (LiveRangeMapType::iterator MI = LiveRangeMap.begin();
MI != LiveRangeMap.end(); ++MI) {
if (MI->first && MI->second) {
LiveRange *LR = MI->second;
@@ -48,7 +48,7 @@ LiveRangeInfo::~LiveRangeInfo() {
for (LiveRange::iterator LI = LR->begin(); LI != LR->end(); ++LI)
LiveRangeMap[*LI] = 0;
delete LR;
}
}
@@ -70,14 +70,14 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
for(LiveRange::iterator L2It = L2->begin(); L2It != L2->end(); ++L2It) {
L1->insert(*L2It); // add the var in L2 to L1
LiveRangeMap[*L2It] = L1; // now the elements in L2 should map
//to L1
LiveRangeMap[*L2It] = L1; // now the elements in L2 should map
//to L1
}
// set call interference for L1 from L2
if (L2->isCallInterference())
L1->setCallInterference();
// add the spill costs
L1->addSpillCost(L2->getSpillCost());
@@ -90,7 +90,7 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
// must have the same color.
if (L2->hasSuggestedColor())
L1->setSuggestedColor(L2->getSuggestedColor());
delete L2; // delete L2 as it is no longer needed
}
@@ -103,7 +103,7 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
LiveRange*
LiveRangeInfo::createNewLiveRange(const Value* Def, bool isCC /* = false*/)
{
{
LiveRange* DefRange = new LiveRange(); // Create a new live range,
DefRange->insert(Def); // add Def to it,
LiveRangeMap[Def] = DefRange; // and update the map.
@@ -123,11 +123,11 @@ LiveRangeInfo::createNewLiveRange(const Value* Def, bool isCC /* = false*/)
LiveRange*
LiveRangeInfo::createOrAddToLiveRange(const Value* Def, bool isCC /* = false*/)
{
{
LiveRange *DefRange = LiveRangeMap[Def];
// check if the LR is already there (because of multiple defs)
if (!DefRange) {
if (!DefRange) {
DefRange = createNewLiveRange(Def, isCC);
} else { // live range already exists
DefRange->insert(Def); // add the operand to the range
@@ -140,13 +140,13 @@ LiveRangeInfo::createOrAddToLiveRange(const Value* Def, bool isCC /* = false*/)
//---------------------------------------------------------------------------
// Method for constructing all live ranges in a function. It creates live
// Method for constructing all live ranges in a function. It creates live
// ranges for all values defined in the instruction stream. Also, it
// creates live ranges for all incoming arguments of the function.
//---------------------------------------------------------------------------
void LiveRangeInfo::constructLiveRanges() {
void LiveRangeInfo::constructLiveRanges() {
if (DEBUG_RA >= RA_DEBUG_LiveRanges)
if (DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "Constructing Live Ranges ...\n";
// first find the live ranges for all incoming args of the function since
@@ -154,14 +154,14 @@ void LiveRangeInfo::constructLiveRanges() {
for (Function::const_arg_iterator AI = Meth->arg_begin(); AI != Meth->arg_end(); ++AI)
createNewLiveRange(AI, /*isCC*/ false);
// Now suggest hardware registers for these function args
// Now suggest hardware registers for these function args
MRI.suggestRegs4MethodArgs(Meth, *this);
// Now create LRs for machine instructions. A new LR will be created
// Now create LRs for machine instructions. A new LR will be created
// only for defs in the machine instr since, we assume that all Values are
// defined before they are used. However, there can be multiple defs for
// the same Value in machine instructions.
//
//
// Also, find CALL and RETURN instructions, which need extra work.
//
MachineFunction &MF = MachineFunction::get(Meth);
@@ -170,21 +170,21 @@ void LiveRangeInfo::constructLiveRanges() {
// iterate over all the machine instructions in BB
for(MachineBasicBlock::iterator MInstIterator = MBB.begin();
MInstIterator != MBB.end(); ++MInstIterator) {
MachineInstr *MInst = MInstIterator;
MInstIterator != MBB.end(); ++MInstIterator) {
MachineInstr *MInst = MInstIterator;
// If the machine instruction is a call/return instruction, add it to
// CallRetInstrList for processing its args, ret value, and ret addr.
//
//
if(TM.getInstrInfo()->isReturn(MInst->getOpcode()) ||
TM.getInstrInfo()->isCall(MInst->getOpcode()))
CallRetInstrList.push_back(MInst);
CallRetInstrList.push_back(MInst);
// iterate over explicit MI operands and create a new LR
// for each operand that is defined by the instruction
for (MachineInstr::val_op_iterator OpI = MInst->begin(),
OpE = MInst->end(); OpI != OpE; ++OpI)
if (OpI.isDef()) {
if (OpI.isDef()) {
const Value *Def = *OpI;
bool isCC = (OpI.getMachineOperand().getType()
== MachineOperand::MO_CCRegister);
@@ -201,7 +201,7 @@ void LiveRangeInfo::constructLiveRanges() {
// iterate over implicit MI operands and create a new LR
// for each operand that is defined by the instruction
for (unsigned i = 0; i < MInst->getNumImplicitRefs(); ++i)
for (unsigned i = 0; i < MInst->getNumImplicitRefs(); ++i)
if (MInst->getImplicitOp(i).isDef()) {
const Value *Def = MInst->getImplicitRef(i);
LiveRange* LR = createOrAddToLiveRange(Def, /*isCC*/ false);
@@ -222,10 +222,10 @@ void LiveRangeInfo::constructLiveRanges() {
// Now we have to suggest clors for call and return arg live ranges.
// Also, if there are implicit defs (e.g., retun value of a call inst)
// they must be added to the live range list
//
//
suggestRegs4CallRets();
if( DEBUG_RA >= RA_DEBUG_LiveRanges)
if( DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "Initial Live Ranges constructed!\n";
}
@@ -235,7 +235,7 @@ void LiveRangeInfo::constructLiveRanges() {
// (e.g., for outgoing call args), suggesting of colors for such live
// ranges is done using target specific function. Those functions are called
// from this function. The target specific methods must:
// 1) suggest colors for call and return args.
// 1) suggest colors for call and return args.
// 2) create new LRs for implicit defs in machine instructions
//---------------------------------------------------------------------------
void LiveRangeInfo::suggestRegs4CallRets() {
@@ -248,7 +248,7 @@ void LiveRangeInfo::suggestRegs4CallRets() {
MRI.suggestReg4RetValue(MInst, *this);
else if (TM.getInstrInfo()->isCall(OpCode))
MRI.suggestRegs4CallArgs(MInst, *this);
else
else
assert( 0 && "Non call/ret instr in CallRetInstrList" );
}
}
@@ -268,7 +268,7 @@ void LiveRangeInfo::suggestRegs4CallRets() {
if the def and op do not interfere //i.e., not simultaneously live
if (degree(LR of def) + degree(LR of op)) <= # avail regs
if both LRs do not have suggested colors
merge2IGNodes(def, op) // i.e., merge 2 LRs
merge2IGNodes(def, op) // i.e., merge 2 LRs
*/
//---------------------------------------------------------------------------
@@ -276,7 +276,7 @@ void LiveRangeInfo::suggestRegs4CallRets() {
// Checks if live range LR interferes with any node assigned or suggested to
// be assigned the specified color
//
//
inline bool InterferesWithColor(const LiveRange& LR, unsigned color) {
IGNode* lrNode = LR.getUserIGNode();
for (unsigned n=0, NN = lrNode->getNumOfNeighbors(); n < NN; n++) {
@@ -295,7 +295,7 @@ inline bool InterferesWithColor(const LiveRange& LR, unsigned color) {
// (but if the colors are the same, it is definitely safe to coalesce)
// (3) LR1 has color and LR2 interferes with any LR that has the same color
// (4) LR2 has color and LR1 interferes with any LR that has the same color
//
//
inline bool InterfsPreventCoalescing(const LiveRange& LROfDef,
const LiveRange& LROfUse) {
// (4) if they have different suggested colors, cannot coalesce
@@ -318,9 +318,9 @@ inline bool InterfsPreventCoalescing(const LiveRange& LROfDef,
}
void LiveRangeInfo::coalesceLRs()
void LiveRangeInfo::coalesceLRs()
{
if(DEBUG_RA >= RA_DEBUG_LiveRanges)
if(DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "\nCoalescing LRs ...\n";
MachineFunction &MF = MachineFunction::get(Meth);
@@ -364,7 +364,7 @@ void LiveRangeInfo::coalesceLRs()
if (!RCOfDef->getInterference(LROfDef, LROfUse) ) {
unsigned CombinedDegree =
LROfDef->getUserIGNode()->getNumOfNeighbors() +
LROfDef->getUserIGNode()->getNumOfNeighbors() +
LROfUse->getUserIGNode()->getNumOfNeighbors();
if (CombinedDegree > RCOfDef->getNumOfAvailRegs()) {
@@ -390,7 +390,7 @@ void LiveRangeInfo::coalesceLRs()
} // for all machine instructions
} // for all BBs
if (DEBUG_RA >= RA_DEBUG_LiveRanges)
if (DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "\nCoalescing Done!\n";
}
@@ -402,7 +402,7 @@ void LiveRangeInfo::printLiveRanges() {
std::cerr << "\nPrinting Live Ranges from Hash Map:\n";
for( ; HMI != LiveRangeMap.end(); ++HMI) {
if (HMI->first && HMI->second) {
std::cerr << " Value* " << RAV(HMI->first) << "\t: ";
std::cerr << " Value* " << RAV(HMI->first) << "\t: ";
if (IGNode* igNode = HMI->second->getUserIGNode())
std::cerr << "LR# " << igNode->getIndex();
else
+14 -14
View File
@@ -1,18 +1,18 @@
//===-- LiveRangeInfo.h - Track all LiveRanges for a Function ----*- C++ -*-==//
//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//
// This file contains the class LiveRangeInfo which constructs and keeps
// This file contains the class LiveRangeInfo which constructs and keeps
// the LiveRangeMap which contains all the live ranges used in a method.
//
// Assumptions:
// Assumptions:
//
// All variables (llvm Values) are defined before they are used. However, a
// All variables (llvm Values) are defined before they are used. However, a
// constant may not be defined in the machine instruction stream if it can be
// used as an immediate value within a machine instruction. However, register
// allocation does not have to worry about immediate constants since they
@@ -45,16 +45,16 @@ typedef hash_map<const Value*, LiveRange*> LiveRangeMapType;
//----------------------------------------------------------------------------
// Class LiveRangeInfo
//
// Constructs and keeps the LiveRangeMap which contains all the live
// Constructs and keeps the LiveRangeMap which contains all the live
// ranges used in a method. Also contain methods to coalesce live ranges.
//----------------------------------------------------------------------------
class LiveRangeInfo {
const Function *const Meth; // Func for which live range info is held
LiveRangeMapType LiveRangeMap; // A map from Value * to LiveRange * to
LiveRangeMapType LiveRangeMap; // A map from Value * to LiveRange * to
// record all live ranges in a method
// created by constructLiveRanges
const TargetMachine& TM; // target machine description
std::vector<RegClass *> & RegClassList;// vector containing register classess
@@ -76,8 +76,8 @@ class LiveRangeInfo {
void suggestRegs4CallRets ();
public:
LiveRangeInfo(const Function *F,
LiveRangeInfo(const Function *F,
const TargetMachine& tm,
std::vector<RegClass *> & RCList);
@@ -89,10 +89,10 @@ public:
// Main entry point for live range construction
//
void constructLiveRanges();
/// return the common live range map for this method
///
inline const LiveRangeMapType *getLiveRangeMap() const
inline const LiveRangeMapType *getLiveRangeMap() const
{ return &LiveRangeMap; }
/// Method used to get the live range containing a Value.
@@ -109,7 +109,7 @@ public:
/// Method for coalescing live ranges. Called only after interference info
/// is calculated.
///
void coalesceLRs();
void coalesceLRs();
/// debugging method to print the live ranges
///
@@ -118,4 +118,4 @@ public:
} // End llvm namespace
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More