#include "llvm/CodeGen/InstrSelectionSupport.h"
#include "llvm/CodeGen/InstrForest.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
-#include "llvm/CodeGen/MachineCodeForBasicBlock.h"
-#include "llvm/CodeGen/MachineCodeForMethod.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/MachineRegInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Function.h"
#include "llvm/iPHINode.h"
#include "llvm/Pass.h"
#include "Support/CommandLine.h"
+#include "Support/LeakDetector.h"
using std::cerr;
using std::vector;
TargetMachine &Target;
void InsertCodeForPhis(Function &F);
void InsertPhiElimInstructions(BasicBlock *BB,
- const std::vector<MachineInstr*>& CpVec);
+ const vector<MachineInstr*>& CpVec);
void SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt);
void PostprocessMachineCodeForTree(InstructionNode* instrNode,
int ruleForNode, short* nts);
public:
InstructionSelection(TargetMachine &T) : Target(T) {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+ }
bool runOnFunction(Function &F);
};
static RegisterLLC<InstructionSelection>
X("instselect", "Instruction Selection", createInstructionSelectionPass);
+TmpInstruction::TmpInstruction(Value *s1, Value *s2, const std::string &name)
+ : Instruction(s1->getType(), Instruction::UserOp1, name) {
+ Operands.push_back(Use(s1, this)); // s1 must be nonnull
+ if (s2) {
+ Operands.push_back(Use(s2, this));
+ }
+
+ // TmpInstructions should not be garbage checked.
+ LeakDetector::removeGarbageObject(this);
+}
+
+// Constructor that requires the type of the temporary to be specified.
+// Both S1 and S2 may be NULL.(
+TmpInstruction::TmpInstruction(const Type *Ty, Value *s1, Value* s2,
+ const std::string &name)
+ : Instruction(Ty, Instruction::UserOp1, name) {
+ if (s1) { Operands.push_back(Use(s1, this)); }
+ if (s2) { Operands.push_back(Use(s2, this)); }
+
+ // TmpInstructions should not be garbage checked.
+ LeakDetector::removeGarbageObject(this);
+}
+
bool InstructionSelection::runOnFunction(Function &F)
{
}
//
- // Record instructions in the vector for each basic block
+ // Create the MachineBasicBlock records and add all of the MachineInstrs
+ // defined in the MachineCodeForInstruction objects to also live in the
+ // MachineBasicBlock objects.
//
- for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI)
+ MachineFunction &MF = MachineFunction::get(&F);
+ for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
+ MachineBasicBlock *MCBB = new MachineBasicBlock(BI);
+ MF.getBasicBlockList().push_back(MCBB);
+
for (BasicBlock::iterator II = BI->begin(); II != BI->end(); ++II) {
MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(II);
- MachineCodeForBasicBlock &MCBB = MachineCodeForBasicBlock::get(BI);
- MCBB.insert(MCBB.end(), mvec.begin(), mvec.end());
+ MCBB->insert(MCBB->end(), mvec.begin(), mvec.end());
}
+ }
// Insert phi elimination code
InsertCodeForPhis(F);
if (SelectDebugLevel >= Select_PrintMachineCode)
{
cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n";
- MachineCodeForMethod::get(&F).dump();
+ MachineFunction::get(&F).dump();
}
return true;
{
// for all basic blocks in function
//
- for (Function::iterator BB = F.begin(); BB != F.end(); ++BB) {
- BasicBlock::InstListType &InstList = BB->getInstList();
- for (BasicBlock::iterator IIt = InstList.begin();
+ MachineFunction &MF = MachineFunction::get(&F);
+ for (MachineFunction::iterator BB = MF.begin(); BB != MF.end(); ++BB) {
+ for (BasicBlock::iterator IIt = BB->getBasicBlock()->begin();
PHINode *PN = dyn_cast<PHINode>(&*IIt); ++IIt) {
// FIXME: This is probably wrong...
Value *PhiCpRes = new PHINode(PN->getType(), "PhiCp:");
-
+
+ // The leak detector shouldn't track these nodes. They are not garbage,
+ // even though their parent field is never filled in.
+ //
+ LeakDetector::removeGarbageObject(PhiCpRes);
+
// for each incoming value of the phi, insert phi elimination
//
for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) {
vector<MachineInstr*> mvec;
Target.getRegInfo().cpValue2Value(PhiCpRes, PN, mvec);
-
- // get an iterator to machine instructions in the BB
- MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(BB);
-
- bbMvec.insert(bbMvec.begin(), mvec.begin(), mvec.end());
+ BB->insert(BB->begin(), mvec.begin(), mvec.end());
} // for each Phi Instr in BB
} // for all BBs in function
}
void
InstructionSelection::InsertPhiElimInstructions(BasicBlock *BB,
- const std::vector<MachineInstr*>& CpVec)
+ const vector<MachineInstr*>& CpVec)
{
Instruction *TermInst = (Instruction*)BB->getTerminator();
MachineCodeForInstruction &MC4Term = MachineCodeForInstruction::get(TermInst);
MachineInstr *FirstMIOfTerm = MC4Term.front();
-
assert (FirstMIOfTerm && "No Machine Instrs for terminator");
-
- MachineCodeForBasicBlock &bbMvec = MachineCodeForBasicBlock::get(BB);
+
+ MachineFunction &MF = MachineFunction::get(BB->getParent());
+ MachineBasicBlock *MBB;
+
+ // FIXME: if PHI instructions existed in the machine code, this would be
+ // unnecesary.
+ for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
+ if (I->getBasicBlock() == BB) {
+ MBB = I;
+ break;
+ }
// find the position of first machine instruction generated by the
// terminator of this BB
- MachineCodeForBasicBlock::iterator MCIt =
- std::find(bbMvec.begin(), bbMvec.end(), FirstMIOfTerm);
+ MachineBasicBlock::iterator MCIt =
+ std::find(MBB->begin(), MBB->end(), FirstMIOfTerm);
- assert( MCIt != bbMvec.end() && "Start inst of terminator not found");
+ assert(MCIt != MBB->end() && "Start inst of terminator not found");
// insert the copy instructions just before the first machine instruction
// generated for the terminator
- bbMvec.insert(MCIt, CpVec.begin(), CpVec.end());
+ MBB->insert(MCIt, CpVec.begin(), CpVec.end());
}
//
if (treeRoot->opLabel != VRegListOp)
{
- std::vector<MachineInstr*> minstrVec;
+ vector<MachineInstr*> minstrVec;
InstructionNode* instrNode = (InstructionNode*)treeRoot;
assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode);
//
Instruction* vmInstr = instrNode->getInstruction();
MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(vmInstr);
- for (int i = (int) mvec.size()-1; i >= 0; i--)
+ for (unsigned i = mvec.size(); i != 0; --i)
{
- std::vector<MachineInstr*> loadConstVec =
- FixConstantOperandsForInstr(vmInstr, mvec[i], Target);
+ vector<MachineInstr*> loadConstVec =
+ FixConstantOperandsForInstr(vmInstr, mvec[i-1], Target);
- if (loadConstVec.size() > 0)
- mvec.insert(mvec.begin()+i, loadConstVec.begin(), loadConstVec.end());
+ mvec.insert(mvec.begin()+i-1, loadConstVec.begin(), loadConstVec.end());
}
}