diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2003-06-05 21:12:56 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2003-06-05 21:12:56 +0000 |
commit | cf819454e4969dcb79a0c32c2638addd85d8fe3a (patch) | |
tree | cb26064419831add3e801a64a09e9b46417abdcb /lib | |
parent | 9783301b9dc88a1c65085bf84314b30b9c2d4e53 (diff) | |
download | llvm-cf819454e4969dcb79a0c32c2638addd85d8fe3a.tar.gz |
Minor tuning -- avoid a non-inlinable function call on every operand.
Also, reorder a couple of functions for inlining.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6635 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/SparcV9/SparcV9PreSelection.cpp | 142 |
1 files changed, 72 insertions, 70 deletions
diff --git a/lib/Target/SparcV9/SparcV9PreSelection.cpp b/lib/Target/SparcV9/SparcV9PreSelection.cpp index a4e6d7a43124..1d8bb80bb87d 100644 --- a/lib/Target/SparcV9/SparcV9PreSelection.cpp +++ b/lib/Target/SparcV9/SparcV9PreSelection.cpp @@ -115,6 +115,7 @@ namespace { class PreSelection : public BasicBlockPass, public InstVisitor<PreSelection> { const TargetMachine ⌖ + const TargetInstrInfo &instrInfo; Function* function; GlobalVariable* getGlobalForConstant(Constant* CV) { @@ -123,7 +124,8 @@ namespace { } public: - PreSelection (const TargetMachine &T): target(T), function(NULL) {} + PreSelection (const TargetMachine &T): + target(T), instrInfo(T.getInstrInfo()), function(NULL) {} // runOnBasicBlock - apply this pass to each BB bool runOnBasicBlock(BasicBlock &BB) { @@ -237,6 +239,75 @@ static Instruction* DecomposeConstantExpr(ConstantExpr* CE, //------------------------------------------------------------------------------ // Instruction visitor methods to perform instruction-specific operations //------------------------------------------------------------------------------ +inline void +PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum, + Instruction& insertBefore) +{ + if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) { + I.setOperand(opNum, gep); // replace global operand + return; + } + + Constant* CV = dyn_cast<Constant>(Op); + if (CV == NULL) + return; + + if (ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) + { // load-time constant: factor it out so we optimize as best we can + Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore); + I.setOperand(opNum, computeConst); // replace expr operand with result + } + else if (instrInfo.ConstantTypeMustBeLoaded(CV)) + { // load address of constant into a register, then load the constant + GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV), + insertBefore); + LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore); + I.setOperand(opNum, ldI); // replace operand with copy in v.reg. + } + else if (instrInfo.ConstantMayNotFitInImmedField(CV, &I)) + { // put the constant into a virtual register using a cast + CastInst* castI = new CastInst(CV, CV->getType(), "copyConst", + &insertBefore); + I.setOperand(opNum, castI); // replace operand with copy in v.reg. + } +} + +// visitOperands() transforms individual operands of all instructions: +// -- Load "large" int constants into a virtual register. What is large +// depends on the type of instruction and on the target architecture. +// -- For any constants that cannot be put in an immediate field, +// load address into virtual register first, and then load the constant. +// +// firstOp and lastOp can be used to skip leading and trailing operands. +// If lastOp is 0, it defaults to #operands or #incoming Phi values. +// +inline void +PreSelection::visitOperands(Instruction &I, int firstOp, int lastOp) +{ + // For any instruction other than PHI, copies go just before the instr. + // For a PHI, operand copies must be before the terminator of the + // appropriate predecessor basic block. Remaining logic is simple + // so just handle PHIs and other instructions separately. + // + if (PHINode* phi = dyn_cast<PHINode>(&I)) + { + if (lastOp == 0) + lastOp = phi->getNumIncomingValues(); + for (unsigned i=firstOp, N=lastOp; i < N; ++i) + this->visitOneOperand(I, phi->getIncomingValue(i), + phi->getOperandNumForIncomingValue(i), + * phi->getIncomingBlock(i)->getTerminator()); + } + else + { + if (lastOp == 0) + lastOp = I.getNumOperands(); + for (unsigned i=firstOp, N=lastOp; i < N; ++i) + this->visitOneOperand(I, I.getOperand(i), i, I); + } +} + + // Common work for *all* instructions. This needs to be called explicitly // by other visit<InstructionType> functions. @@ -329,75 +400,6 @@ PreSelection::visitCallInst(CallInst &I) } -// visitOperands() transforms individual operands of all instructions: -// -- Load "large" int constants into a virtual register. What is large -// depends on the type of instruction and on the target architecture. -// -- For any constants that cannot be put in an immediate field, -// load address into virtual register first, and then load the constant. -// -// firstOp and lastOp can be used to skip leading and trailing operands. -// If lastOp is 0, it defaults to #operands or #incoming Phi values. -// -void -PreSelection::visitOperands(Instruction &I, int firstOp, int lastOp) -{ - // For any instruction other than PHI, copies go just before the instr. - // For a PHI, operand copies must be before the terminator of the - // appropriate predecessor basic block. Remaining logic is simple - // so just handle PHIs and other instructions separately. - // - if (PHINode* phi = dyn_cast<PHINode>(&I)) - { - if (lastOp == 0) - lastOp = phi->getNumIncomingValues(); - for (unsigned i=firstOp, N=lastOp; i < N; ++i) - this->visitOneOperand(I, phi->getIncomingValue(i), - phi->getOperandNumForIncomingValue(i), - * phi->getIncomingBlock(i)->getTerminator()); - } - else - { - if (lastOp == 0) - lastOp = I.getNumOperands(); - for (unsigned i=firstOp, N=lastOp; i < N; ++i) - this->visitOneOperand(I, I.getOperand(i), i, I); - } -} - -void -PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum, - Instruction& insertBefore) -{ - if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) { - I.setOperand(opNum, gep); // replace global operand - return; - } - - Constant* CV = dyn_cast<Constant>(Op); - if (CV == NULL) - return; - - if (ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) - { // load-time constant: factor it out so we optimize as best we can - Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore); - I.setOperand(opNum, computeConst); // replace expr operand with result - } - else if (target.getInstrInfo().ConstantTypeMustBeLoaded(CV)) - { // load address of constant into a register, then load the constant - GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV), - insertBefore); - LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore); - I.setOperand(opNum, ldI); // replace operand with copy in v.reg. - } - else if (target.getInstrInfo().ConstantMayNotFitInImmedField(CV, &I)) - { // put the constant into a virtual register using a cast - CastInst* castI = new CastInst(CV, CV->getType(), "copyConst", - &insertBefore); - I.setOperand(opNum, castI); // replace operand with copy in v.reg. - } -} - - //===----------------------------------------------------------------------===// // createPreSelectionPass - Public entrypoint for pre-selection pass // and this file as a whole... |