summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp')
-rw-r--r--llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp308
1 files changed, 0 insertions, 308 deletions
diff --git a/llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp b/llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp
deleted file mode 100644
index a13019e2061..00000000000
--- a/llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-//===- SparcV9PreSelection.cpp - Specialize LLVM code for SparcV9 ---------===//
-//
-// 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 PreSelection pass which specializes LLVM code for
-// the SparcV9 instruction selector, while remaining in legal portable LLVM
-// form and preserving type information and type safety. This is meant to enable
-// dataflow optimizations on SparcV9-specific operations such as accesses to
-// constants, globals, and array indexing.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV9Internals.h"
-#include "SparcV9BurgISel.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Scalar.h"
-#include <algorithm>
-using namespace llvm;
-
-namespace {
-
- //===--------------------------------------------------------------------===//
- // PreSelection Pass - Specialize LLVM code for the SparcV9 instr. selector.
- //
- class PreSelection : public FunctionPass, public InstVisitor<PreSelection> {
- const TargetInstrInfo &instrInfo;
-
- public:
- PreSelection(const TargetMachine &T)
- : instrInfo(*T.getInstrInfo()) {}
-
- // runOnFunction - apply this pass to each Function
- bool runOnFunction(Function &F) {
- visit(F);
- return true;
- }
- const char *getPassName() const { return "SparcV9 Instr. Pre-selection"; }
-
- // These methods do the actual work of specializing code
- void visitInstruction(Instruction &I); // common work for every instr.
- void visitGetElementPtrInst(GetElementPtrInst &I);
- void visitCallInst(CallInst &I);
- void visitPHINode(PHINode &PN);
-
- void visitBasicBlock(BasicBlock &BB) {
- if (isa<UnreachableInst>(BB.getTerminator())) {
- BB.getInstList().pop_back();
- const Type *RetTy = BB.getParent()->getReturnType();
- Value *RetVal = RetTy == Type::VoidTy ? 0 : UndefValue::get(RetTy);
- new ReturnInst(RetVal, &BB);
- }
- }
-
- // Helper functions for visiting operands of every instruction
- //
- // visitOperands() works on every operand in [firstOp, lastOp-1].
- // If lastOp==0, lastOp defaults to #operands or #incoming Phi values.
- //
- // visitOneOperand() does all the work for one operand.
- //
- void visitOperands(Instruction &I, int firstOp=0);
- void visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
- Instruction& insertBefore);
- };
-
-#if 0
- // Register the pass...
- RegisterPass<PreSelection> X("preselect",
- "Specialize LLVM code for a target machine"
- createPreselectionPass);
-#endif
-
-} // end anonymous namespace
-
-
-//------------------------------------------------------------------------------
-// Helper functions used by methods of class PreSelection
-//------------------------------------------------------------------------------
-
-
-// getGlobalAddr(): Put address of a global into a v. register.
-static GetElementPtrInst* getGlobalAddr(Value* ptr, Instruction& insertBefore) {
-
- return (isa<GlobalVariable>(ptr))
- ? new GetElementPtrInst(ptr,
- std::vector<Value*>(1, ConstantSInt::get(Type::LongTy, 0U)),
- "addrOfGlobal:" + ptr->getName(), &insertBefore)
- : NULL;
-}
-
-// Wrapper on Constant::classof to use in find_if
-inline static bool nonConstant(const Use& U) {
- return ! isa<Constant>(U);
-}
-
-static Instruction* DecomposeConstantExpr(ConstantExpr* CE,
- Instruction& insertBefore)
-{
- Value *getArg1, *getArg2;
-
- switch(CE->getOpcode())
- {
- case Instruction::Cast:
- getArg1 = CE->getOperand(0);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg1))
- getArg1 = DecomposeConstantExpr(CEarg, insertBefore);
- return new CastInst(getArg1, CE->getType(), "constantCast",&insertBefore);
-
- case Instruction::GetElementPtr:
- assert(std::find_if(CE->op_begin()+1, CE->op_end(),
- nonConstant) == CE->op_end()
- && "All indices in ConstantExpr getelementptr must be constant!");
- getArg1 = CE->getOperand(0);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg1))
- getArg1 = DecomposeConstantExpr(CEarg, insertBefore);
- else if (GetElementPtrInst* gep = getGlobalAddr(getArg1, insertBefore))
- getArg1 = gep;
- return new GetElementPtrInst(getArg1,
- std::vector<Value*>(CE->op_begin()+1, CE->op_end()),
- "constantGEP:" + getArg1->getName(), &insertBefore);
-
- case Instruction::Select: {
- Value *C, *S1, *S2;
- C = CE->getOperand (0);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr> (C))
- C = DecomposeConstantExpr (CEarg, insertBefore);
- S1 = CE->getOperand (1);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr> (S1))
- S1 = DecomposeConstantExpr (CEarg, insertBefore);
- S2 = CE->getOperand (2);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr> (S2))
- S2 = DecomposeConstantExpr (CEarg, insertBefore);
- return new SelectInst (C, S1, S2, "constantSelect", &insertBefore);
- }
-
- case Instruction::Shr: {
- getArg1 = CE->getOperand(0);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg1))
- getArg1 = DecomposeConstantExpr(CEarg, insertBefore);
- getArg2 = CE->getOperand(1);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg2))
- getArg2 = DecomposeConstantExpr(CEarg, insertBefore);
- return new ShiftInst (static_cast<Instruction::OtherOps>(CE->getOpcode()),
- getArg1, getArg2,
- "constantShr:" + getArg1->getName(), &insertBefore);
- }
-
- case Instruction::Shl: {
- getArg1 = CE->getOperand(0);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg1))
- getArg1 = DecomposeConstantExpr(CEarg, insertBefore);
- getArg2 = CE->getOperand(1);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg2))
- getArg2 = DecomposeConstantExpr(CEarg, insertBefore);
- return new ShiftInst (static_cast<Instruction::OtherOps>(CE->getOpcode()),
- getArg1, getArg2,
- "constantShl:" + getArg1->getName(), &insertBefore);
- }
-
- default: // must be a binary operator
- assert(CE->getOpcode() >= Instruction::BinaryOpsBegin &&
- CE->getOpcode() < Instruction::BinaryOpsEnd &&
- "Unhandled opcode in ConstantExpr");
- getArg1 = CE->getOperand(0);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg1))
- getArg1 = DecomposeConstantExpr(CEarg, insertBefore);
- getArg2 = CE->getOperand(1);
- if (ConstantExpr* CEarg = dyn_cast<ConstantExpr>(getArg2))
- getArg2 = DecomposeConstantExpr(CEarg, insertBefore);
- return BinaryOperator::create((Instruction::BinaryOps) CE->getOpcode(),
- getArg1, getArg2,
- "constantBinaryOp", &insertBefore);
- }
-}
-
-static inline bool ConstantTypeMustBeLoaded(const Type* CVT) {
- assert(CVT->isPrimitiveType() || isa<PointerType>(CVT));
- return !(CVT->isIntegral() || isa<PointerType>(CVT));
-}
-
-//------------------------------------------------------------------------------
-// Instruction visitor methods to perform instruction-specific operations
-//------------------------------------------------------------------------------
-inline void
-PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
- Instruction& insertBefore)
-{
- assert(&insertBefore != NULL && "Must have instruction to insert before.");
-
- if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) {
- I.setOperand(opNum, gep); // replace global operand
- return; // nothing more to do for this op.
- }
-
- 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 (ConstantTypeMustBeLoaded(CV->getType())) {
- // load address of constant into a register, then load the constant
- // this is now done during instruction selection
- // the constant will live in the MachineConstantPool later on
- } else if (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 - transform 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) {
- // For any instruction other than PHI, copies go just before the instr.
- for (unsigned i = firstOp, e = I.getNumOperands(); i != e; ++i)
- visitOneOperand(I, I.getOperand(i), i, I);
-}
-
-
-void PreSelection::visitPHINode(PHINode &PN) {
- // 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.
- //
- for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
- visitOneOperand(PN, PN.getIncomingValue(i),
- PN.getOperandNumForIncomingValue(i),
- *PN.getIncomingBlock(i)->getTerminator());
- // do not call visitOperands!
-}
-
-// Common work for *all* instructions. This needs to be called explicitly
-// by other visit<InstructionType> functions.
-inline void PreSelection::visitInstruction(Instruction &I) {
- visitOperands(I); // Perform operand transformations
-}
-
-// GetElementPtr instructions: check if pointer is a global
-void PreSelection::visitGetElementPtrInst(GetElementPtrInst &I) {
- Instruction* curI = &I;
-
- // The Sparc backend doesn't handle array indexes that are not long types, so
- // insert a cast from whatever it is to long, if the sequential type index is
- // not a long already.
- unsigned Idx = 1;
- for (gep_type_iterator TI = gep_type_begin(I), E = gep_type_end(I); TI != E;
- ++TI, ++Idx)
- if (isa<SequentialType>(*TI) &&
- I.getOperand(Idx)->getType() != Type::LongTy) {
- Value *Op = I.getOperand(Idx);
- if (Op->getType()->isUnsigned()) // Must sign extend!
- Op = new CastInst(Op, Op->getType()->getSignedVersion(), "v9", &I);
- if (Op->getType() != Type::LongTy)
- Op = new CastInst(Op, Type::LongTy, "v9", &I);
- I.setOperand(Idx, Op);
- }
-
-
- // Decompose multidimensional array references
- if (I.getNumIndices() >= 2) {
- // DecomposeArrayRef() replaces I and deletes it, if successful,
- // so remember predecessor in order to find the replacement instruction.
- // Also remember the basic block in case there is no predecessor.
- Instruction* prevI = I.getPrev();
- BasicBlock* bb = I.getParent();
- if (DecomposeArrayRef(&I))
- // first instr. replacing I
- curI = cast<GetElementPtrInst>(prevI? prevI->getNext() : &bb->front());
- }
-
- // Perform other transformations common to all instructions
- visitInstruction(*curI);
-}
-
-void PreSelection::visitCallInst(CallInst &I) {
- // Tell visitOperands to ignore the function name if this is a direct call.
- visitOperands(I, (/*firstOp=*/ I.getCalledFunction()? 1 : 0));
-}
-
-/// createPreSelectionPass - Public entry point for the PreSelection pass
-///
-FunctionPass* llvm::createPreSelectionPass(const TargetMachine &TM) {
- return new PreSelection(TM);
-}
OpenPOWER on IntegriCloud