SCEVExpander(ScalarEvolution &se, LoopInfo &li) : SE(se), LI(li) {}
/// clear - Erase the contents of the InsertedExpressions map so that users
- /// trying to expand the same expression into multiple BasicBlocks or
+ /// trying to expand the same expression into multiple BasicBlocks or
/// different places within the same BasicBlock can do so.
void clear() { InsertedExpressions.clear(); }
-
+
/// isInsertedInstruction - Return true if the specified instruction was
/// inserted by the code rewriter. If so, the client should not modify the
/// instruction.
bool isSigned) {
// First step, figure out the appropriate FP_TO*INT operation to use.
MVT::ValueType NewOutTy = DestVT;
-
+
unsigned OpToUse = 0;
-
+
// Scan for the appropriate larger type to use.
while (1) {
NewOutTy = (MVT::ValueType)(NewOutTy+1);
assert(MVT::isInteger(NewOutTy) && "Ran out of possibilities!");
-
+
// If the target supports FP_TO_SINT returning this type, use it.
switch (TLI.getOperationAction(ISD::FP_TO_SINT, NewOutTy)) {
default: break;
break;
}
if (OpToUse) break;
-
+
// If the target supports FP_TO_UINT of this type, use it.
switch (TLI.getOperationAction(ISD::FP_TO_UINT, NewOutTy)) {
default: break;
break;
}
if (OpToUse) break;
-
+
// Otherwise, try a larger type.
}
-
+
// Make sure to legalize any nodes we create here in the next pass.
NeedsAnotherIteration = true;
-
+
// Okay, we found the operation and type to use. Truncate the result of the
// extended FP_TO_*INT operation to the desired size.
return DAG.getNode(ISD::TRUNCATE, DestVT,
bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case Legal:
- switch (TLI.getOperationAction(Node->getOpcode(),
+ switch (TLI.getOperationAction(Node->getOpcode(),
Node->getOperand(0).getValueType())) {
default: assert(0 && "Unknown operation action!");
case TargetLowering::Expand:
break;
}
break;
-
+
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
switch (getTypeAction(Node->getOperand(0).getValueType())) {
NeedsAnotherIteration = true;
return Result;
}
-
+
if (Tmp1 != Node->getOperand(0))
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
break;
break;
}
break;
-
+
case ISD::ZERO_EXTEND:
case ISD::SIGN_EXTEND:
case ISD::FP_EXTEND:
case Legal: Op = LegalizeOp(Node->getOperand(0)); break;
case Promote: Op = PromoteOp(Node->getOperand(0)); break;
}
-
+
Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_SINT, VT, Op), DAG);
// Now that the custom expander is done, expand the result, which is still
ExpandOp(Op, Lo, Hi);
break;
}
-
+
if (Node->getOperand(0).getValueType() == MVT::f32)
Lo = ExpandLibCall("__fixsfdi", Node, Hi);
else
Lo = ExpandLibCall("__fixdfdi", Node, Hi);
break;
+
case ISD::FP_TO_UINT:
if (TLI.getOperationAction(ISD::FP_TO_UINT, VT) == TargetLowering::Custom) {
SDOperand Op = DAG.getNode(ISD::FP_TO_UINT, VT,
ExpandOp(TLI.LowerOperation(Op, DAG), Lo, Hi);
break;
}
-
+
if (Node->getOperand(0).getValueType() == MVT::f32)
Lo = ExpandLibCall("__fixunssfdi", Node, Hi);
else
inline unsigned char *allocateStub(unsigned StubSize);
inline unsigned char *allocateConstant(unsigned ConstantSize,
unsigned Alignment);
- inline unsigned char* allocateGlobal(unsigned Size,
+ inline unsigned char* allocateGlobal(unsigned Size,
unsigned Alignment);
inline unsigned char *startFunctionBody();
inline void endFunctionBody(unsigned char *FunctionEnd);
// FIXME: We could rewrite all references to this stub if we knew them.
- // What we will do is set the compiled function address to map to the
- // same GOT entry as the stub so that later clients may update the GOT
+ // What we will do is set the compiled function address to map to the
+ // same GOT entry as the stub so that later clients may update the GOT
// if they see it still using the stub address.
// Note: this is done so the Resolver doesn't have to manage GOT memory
// Do this without allocating map space if the target isn't using a GOT
if(MemMgr.isManagingGOT()) {
unsigned idx = getJITResolver(this).getGOTIndexForAddr((void*)CurBlock);
if (((void**)MemMgr.getGOTBase())[idx] != (void*)CurBlock) {
- DEBUG(std::cerr << "GOT was out of date for " << (void*)CurBlock
+ DEBUG(std::cerr << "GOT was out of date for " << (void*)CurBlock
<< " pointing at " << ((void**)MemMgr.getGOTBase())[idx] << "\n");
((void**)MemMgr.getGOTBase())[idx] = (void*)CurBlock;
}
EmitBranchToAt(CameFromStub, Target);
} else {
DEBUG(std::cerr << "confused, didn't come from stub at " << CameFromStub
- << " old jump vector " << oldpv
+ << " old jump vector " << oldpv
<< " new jump vector " << Target << "\n");
}
}
break;
case Alpha::reloc_bsr: {
- idx = (((unsigned char*)MR->getResultPointer() -
+ idx = (((unsigned char*)MR->getResultPointer() -
(unsigned char*)RelocPos) >> 2) + 1; //skip first 2 inst of fun
*RelocPos |= (idx & ((1 << 21)-1));
doCommon = false;
NumBytes += MFI->getMaxCallFrameSize();
}
- // If we are a leaf function, and use up to 224 bytes of stack space,
+ // If we are a leaf function, and use up to 224 bytes of stack space,
// and don't have a frame pointer, then we do not need to adjust the stack
// pointer (we fit in the Red Zone).
if ((NumBytes == 0) || (NumBytes <= 224 && !hasFP(MF) && !MFI->hasCalls())) {
FP_TO_INT16_IN_MEM,
FP_TO_INT32_IN_MEM,
FP_TO_INT64_IN_MEM,
-
+
/// CALL/TAILCALL - These operations represent an abstract X86 call
/// instruction, which includes a bunch of information. In particular the
/// operands of these node are:
setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom);
setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom);
}
-
+
// Handle FP_TO_UINT by promoting the destination to a larger signed
// conversion.
setOperationAction(ISD::FP_TO_UINT , MVT::i1 , Promote);
// this operation.
setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote);
setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote);
-
+
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand);
case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
}
-
+
// Build the FP_TO_INT*_IN_MEM
std::vector<SDOperand> Ops;
Ops.push_back(DAG.getEntryNode());
Ops.push_back(Op.getOperand(0));
Ops.push_back(StackSlot);
SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops);
-
+
// Load the result.
return DAG.getLoad(Op.getValueType(), FIST, StackSlot,
DAG.getSrcValue(NULL));
addFullAddress(BuildMI(BB, X86::FILD64m, 4, Result), AM);
}
return Result;
-
+
case ISD::EXTLOAD: // Arbitrarily codegen extloads as MOVZX*
case ISD::ZEXTLOAD: {
// Make sure we generate both values.
ExprMap.erase(N);
SelectExpr(N.getValue(0));
return;
-
+
case X86ISD::FP_TO_INT16_IN_MEM:
case X86ISD::FP_TO_INT32_IN_MEM:
case X86ISD::FP_TO_INT64_IN_MEM: {
SelectAddress(N.getOperand(2), AM);
ValReg = SelectExpr(N.getOperand(1));
}
-
+
// Change the floating point control register to use "round towards zero"
// mode when truncating to an integer value.
//
MachineFunction *F = BB->getParent();
int CWFrameIdx = F->getFrameInfo()->CreateStackObject(2, 2);
addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx);
-
+
// Load the old value of the high byte of the control word...
unsigned OldCW = MakeReg(MVT::i16);
addFrameReference(BuildMI(BB, X86::MOV16rm, 4, OldCW), CWFrameIdx);
-
+
// Set the high part to be round to zero...
addFrameReference(BuildMI(BB, X86::MOV16mi, 5), CWFrameIdx).addImm(0xC7F);
-
+
// Reload the modified control word now...
addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
-
+
// Restore the memory image of control word to original value
addFrameReference(BuildMI(BB, X86::MOV16mr, 5), CWFrameIdx).addReg(OldCW);
case X86ISD::FP_TO_INT32_IN_MEM: Tmp1 = X86::FIST32m; break;
case X86ISD::FP_TO_INT64_IN_MEM: Tmp1 = X86::FISTP64m; break;
}
-
+
addFullAddress(BuildMI(BB, Tmp1, 5), AM).addReg(ValReg);
-
+
// Reload the original control word now.
addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
return;
if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(AddRec->getOperand(1)))
if (SU->getValue()->getType()->isUnsigned())
return true;
-
+
// Otherwise, no, we can't handle it yet.
return false;
}
// This index is scaled by the type size being indexed.
if (TySize != 1)
- Result = SCEVMulExpr::get(Result,
+ Result = SCEVMulExpr::get(Result,
SCEVConstant::get(ConstantUInt::get(UIntPtrTy,
TySize)));
return Result;
Value *BasePtr;
if (Constant *CB = dyn_cast<Constant>(GEP->getOperand(0)))
BasePtr = ConstantExpr::getCast(CB, UIntPtrTy);
- else {
+ else {
Value *&BP = CastedBasePointers[GEP->getOperand(0)];
if (BP == 0) {
BasicBlock::iterator InsertPt;
DEBUG(std::cerr << "FOUND USER: " << *User
<< " OF STRIDE: " << *Step << " BASE = " << *Base << "\n");
-
+
// Okay, we found a user that we cannot reduce. Analyze the instruction
// and decide what to do with it.
IVUsesByStride[Step].addUser(Base, User, GEP);
assert(Step->getType()->isUnsigned() && "Bad step value!");
std::set<GetElementPtrInst*> AnalyzedGEPs;
-
+
for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;++UI){
Instruction *User = cast<Instruction>(*UI);
if (LI->getLoopFor(User->getParent()) != L)
continue;
- // Next, see if this user is analyzable itself!
+ // Next, see if this user is analyzable itself!
if (!AddUsersIfInteresting(User, L)) {
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(User)) {
// If this is a getelementptr instruction, figure out what linear
// expression of induction variable is actually being used.
- //
+ //
if (AnalyzedGEPs.insert(GEP).second) // Not already analyzed?
AnalyzeGetElementPtrUsers(GEP, I, L);
} else {
/// isTargetConstant - Return true if the following can be referenced by the
/// immediate field of a target instruction.
static bool isTargetConstant(const SCEVHandle &V) {
-
+
// FIXME: Look at the target to decide if &GV is a legal constant immediate.
if (isa<SCEVConstant>(V)) return true;
-
+
return false; // ENABLE this for x86
-
+
if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V))
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(SU->getValue()))
if (CE->getOpcode() == Instruction::Cast)
for (; i != SAE->getNumOperands(); ++i)
if (isTargetConstant(SAE->getOperand(i))) {
SCEVHandle ImmVal = SAE->getOperand(i);
-
+
// If there are any other immediates that we can handle here, pull them
// out too.
for (++i; i != SAE->getNumOperands(); ++i)
// eventually emit the object.
std::vector<std::pair<SCEVHandle, BasedUser> > UsersToProcess;
UsersToProcess.reserve(Uses.Users.size());
-
- SCEVHandle ZeroBase = SCEVUnknown::getIntegerSCEV(0,
+
+ SCEVHandle ZeroBase = SCEVUnknown::getIntegerSCEV(0,
Uses.Users[0].first->getType());
for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i)
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
bool isAddress = isa<LoadInst>(UsersToProcess[i].second.Inst) ||
isa<StoreInst>(UsersToProcess[i].second.Inst);
- UsersToProcess[i].second.Imm = GetImmediateValues(UsersToProcess[i].first,
+ UsersToProcess[i].second.Imm = GetImmediateValues(UsersToProcess[i].first,
isAddress);
UsersToProcess[i].first = SCEV::getMinusSCEV(UsersToProcess[i].first,
UsersToProcess[i].second.Imm);
Instruction *PreInsertPt = Preheader->getTerminator();
Instruction *PhiInsertBefore = L->getHeader()->begin();
- assert(isa<PHINode>(PhiInsertBefore) &&
+ assert(isa<PHINode>(PhiInsertBefore) &&
"How could this loop have IV's without any phis?");
PHINode *SomeLoopPHI = cast<PHINode>(PhiInsertBefore);
assert(SomeLoopPHI->getNumIncomingValues() == 2 &&
"This loop isn't canonicalized right");
BasicBlock *LatchBlock =
SomeLoopPHI->getIncomingBlock(SomeLoopPHI->getIncomingBlock(0) == Preheader);
-
+
// FIXME: This loop needs increasing levels of intelligence.
// STAGE 0: just emit everything as its own base. <-- We are here
// STAGE 1: factor out common vars from bases, and try and push resulting
PHINode *NewPHI = new PHINode(ReplacedTy, Replaced->getName()+".str",
PhiInsertBefore);
- // Emit the initial base value into the loop preheader, and add it to the
+ // Emit the initial base value into the loop preheader, and add it to the
// Phi node.
Value *BaseV = Rewriter.expandCodeFor(UsersToProcess.front().first,
PreInsertPt, ReplacedTy);
// Emit the code to add the immediate offset to the Phi value, just before
// the instruction that we identified as using this stride and base.
- // First, empty the SCEVExpander's expression map so that we are guaranteed
+ // First, empty the SCEVExpander's expression map so that we are guaranteed
// to have the code emitted where we expect it.
Rewriter.clear();
SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(NewPHI),
Value *newVal = Rewriter.expandCodeFor(NewValSCEV,
UsersToProcess.front().second.Inst,
ReplacedTy);
-
+
// Replace the use of the operand Value with the new Phi we just created.
- DEBUG(std::cerr << "REPLACING: " << *Replaced << "IN: " <<
+ DEBUG(std::cerr << "REPLACING: " << *Replaced << "IN: " <<
*UsersToProcess.front().second.Inst << "WITH: "<< *newVal << '\n');
UsersToProcess.front().second.Inst->replaceUsesOfWith(Replaced, newVal);
-
+
// Mark old value we replaced as possibly dead, so that it is elminated
// if we just replaced the last use of that value.
DeadInsts.insert(cast<Instruction>(Replaced));
-
+
UsersToProcess.erase(UsersToProcess.begin());
++NumReduced;
// IMPORTANT TODO: Figure out how to partition the IV's with this stride, but
// different starting values, into different PHIs.
-
+
// BEFORE writing this, it's probably useful to handle GEP's.
// NOTE: pull all constants together, for REG+IMM addressing, include &GV in
LLCPassList(cl::desc("Passes Available"));
cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
- cl::desc("Do not verify input module"));
+ cl::desc("Do not verify input module"));
// GetFileNameRoot - Helper function to get the basename of a filename.