//===----------------------------------------------------------------------===//
#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Config/config.h"
#include <fstream>
#include <sstream>
using namespace llvm;
-static AnnotationID MF_AID(
- AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
-
-// Out of line virtual function to home classes.
-void MachineFunctionPass::virtfn() {}
+bool MachineFunctionPass::runOnFunction(Function &F) {
+ // Do not codegen any 'available_externally' functions at all, they have
+ // definitions outside the translation unit.
+ if (F.hasAvailableExternallyLinkage())
+ return false;
+
+ return runOnMachineFunction(MachineFunction::get(&F));
+}
namespace {
struct VISIBILITY_HIDDEN Printer : public MachineFunctionPass {
MachineFunction::MachineFunction(const Function *F,
const TargetMachine &TM)
- : Annotation(MF_AID), Fn(F), Target(TM) {
+ : Annotation(AnnotationManager::getID("CodeGen::MachineCodeForFunction")),
+ Fn(F), Target(TM) {
if (TM.getRegisterInfo())
RegInfo = new (Allocator.Allocate<MachineRegisterInfo>())
MachineRegisterInfo(*TM.getRegisterInfo());
MachineFrameInfo(*TM.getFrameInfo());
ConstantPool = new (Allocator.Allocate<MachineConstantPool>())
MachineConstantPool(TM.getTargetData());
-
+ Alignment = TM.getTargetLowering()->getFunctionAlignment(F);
+
// Set up jump table.
const TargetData &TD = *TM.getTargetData();
bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
- unsigned Alignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
- : TD.getPointerABIAlignment();
+ unsigned TyAlignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
+ : TD.getPointerABIAlignment();
JumpTableInfo = new (Allocator.Allocate<MachineJumpTableInfo>())
- MachineJumpTableInfo(EntrySize, Alignment);
+ MachineJumpTableInfo(EntrySize, TyAlignment);
}
MachineFunction::~MachineFunction() {
BasicBlocks.clear();
InstructionRecycler.clear(Allocator);
BasicBlockRecycler.clear(Allocator);
- if (RegInfo)
- RegInfo->~MachineRegisterInfo(); Allocator.Deallocate(RegInfo);
+ if (RegInfo) {
+ RegInfo->~MachineRegisterInfo();
+ Allocator.Deallocate(RegInfo);
+ }
if (MFInfo) {
- MFInfo->~MachineFunctionInfo(); Allocator.Deallocate(MFInfo);
+ MFInfo->~MachineFunctionInfo();
+ Allocator.Deallocate(MFInfo);
}
FrameInfo->~MachineFrameInfo(); Allocator.Deallocate(FrameInfo);
ConstantPool->~MachineConstantPool(); Allocator.Deallocate(ConstantPool);
/// of `new MachineInstr'.
///
MachineInstr *
-MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID, bool NoImp) {
+MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID,
+ DebugLoc DL, bool NoImp) {
return new (InstructionRecycler.Allocate<MachineInstr>(Allocator))
- MachineInstr(TID, NoImp);
+ MachineInstr(TID, DL, NoImp);
}
/// CloneMachineInstr - Create a new MachineInstr which is a copy of the
OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
}
-/// CFGOnly flag - This is used to control whether or not the CFG graph printer
-/// prints out the contents of basic blocks or not. This is acceptable because
-/// this code is only really used for debugging purposes.
-///
-static bool CFGOnly = false;
-
namespace llvm {
template<>
struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
}
static std::string getNodeLabel(const MachineBasicBlock *Node,
- const MachineFunction *Graph) {
- if (CFGOnly && Node->getBasicBlock() &&
+ const MachineFunction *Graph,
+ bool ShortNames) {
+ if (ShortNames && Node->getBasicBlock() &&
!Node->getBasicBlock()->getName().empty())
return Node->getBasicBlock()->getName() + ":";
std::ostringstream Out;
- if (CFGOnly) {
+ if (ShortNames) {
Out << Node->getNumber() << ':';
return Out.str();
}
void MachineFunction::viewCFGOnly() const
{
- CFGOnly = true;
- viewCFG();
- CFGOnly = false;
+#ifndef NDEBUG
+ ViewGraph(this, "mf" + getFunction()->getName(), true);
+#else
+ cerr << "SelectionDAG::viewGraph is only available in debug builds on "
+ << "systems with Graphviz or gv!\n";
+#endif // NDEBUG
}
// The next two methods are used to construct and to retrieve
MachineFunction&
MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
{
+ AnnotationID MF_AID =
+ AnnotationManager::getID("CodeGen::MachineCodeForFunction");
assert(Fn->getAnnotation(MF_AID) == 0 &&
"Object already exists for this function!");
MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
}
void MachineFunction::destruct(const Function *Fn) {
+ AnnotationID MF_AID =
+ AnnotationManager::getID("CodeGen::MachineCodeForFunction");
bool Deleted = Fn->deleteAnnotation(MF_AID);
assert(Deleted && "Machine code did not exist for function!");
Deleted = Deleted; // silence warning when no assertions.
MachineFunction& MachineFunction::get(const Function *F)
{
+ AnnotationID MF_AID =
+ AnnotationManager::getID("CodeGen::MachineCodeForFunction");
MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
assert(mc && "Call construct() method first to allocate the object");
return *mc;
}
+/// addLiveIn - Add the specified physical register as a live-in value and
+/// create a corresponding virtual register for it.
+unsigned MachineFunction::addLiveIn(unsigned PReg,
+ const TargetRegisterClass *RC) {
+ assert(RC->contains(PReg) && "Not the correct regclass!");
+ unsigned VReg = getRegInfo().createVirtualRegister(RC);
+ getRegInfo().addLiveIn(PReg, VReg);
+ return VReg;
+}
+
+/// getOrCreateDebugLocID - Look up the DebugLocTuple index with the given
+/// source file, line, and column. If none currently exists, create a new
+/// DebugLocTuple, and insert it into the DebugIdMap.
+unsigned MachineFunction::getOrCreateDebugLocID(GlobalVariable *CompileUnit,
+ unsigned Line, unsigned Col) {
+ DebugLocTuple Tuple(CompileUnit, Line, Col);
+ DenseMap<DebugLocTuple, unsigned>::iterator II
+ = DebugLocInfo.DebugIdMap.find(Tuple);
+ if (II != DebugLocInfo.DebugIdMap.end())
+ return II->second;
+ // Add a new tuple.
+ unsigned Id = DebugLocInfo.DebugLocations.size();
+ DebugLocInfo.DebugLocations.push_back(Tuple);
+ DebugLocInfo.DebugIdMap[Tuple] = Id;
+ return Id;
+}
+
+/// getDebugLocTuple - Get the DebugLocTuple for a given DebugLoc object.
+DebugLocTuple MachineFunction::getDebugLocTuple(DebugLoc DL) const {
+ unsigned Idx = DL.getIndex();
+ assert(Idx < DebugLocInfo.DebugLocations.size() &&
+ "Invalid index into debug locations!");
+ return DebugLocInfo.DebugLocations[Idx];
+}
+
//===----------------------------------------------------------------------===//
// MachineFrameInfo implementation
//===----------------------------------------------------------------------===//
return JumpTables.size()-1;
}
+/// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
+/// the jump tables to branch to New instead.
+bool
+MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old,
+ MachineBasicBlock *New) {
+ assert(Old != New && "Not making a change?");
+ bool MadeChange = false;
+ for (size_t i = 0, e = JumpTables.size(); i != e; ++i) {
+ MachineJumpTableEntry &JTE = JumpTables[i];
+ for (size_t j = 0, e = JTE.MBBs.size(); j != e; ++j)
+ if (JTE.MBBs[j] == Old) {
+ JTE.MBBs[j] = New;
+ MadeChange = true;
+ }
+ }
+ return MadeChange;
+}
void MachineJumpTableInfo::print(std::ostream &OS) const {
// FIXME: this is lame, maybe we could print out the MBB numbers or something
// Check to see if we already have this constant.
//
// FIXME, this could be made much more efficient for large constant pools.
- unsigned AlignMask = (1 << Alignment)-1;
for (unsigned i = 0, e = Constants.size(); i != e; ++i)
- if (Constants[i].Val.ConstVal == C && (Constants[i].Offset & AlignMask)== 0)
+ if (Constants[i].Val.ConstVal == C &&
+ (Constants[i].getAlignment() & (Alignment - 1)) == 0)
return i;
- unsigned Offset = 0;
- if (!Constants.empty()) {
- Offset = Constants.back().getOffset();
- Offset += TD->getABITypeSize(Constants.back().getType());
- Offset = (Offset+AlignMask)&~AlignMask;
- }
-
- Constants.push_back(MachineConstantPoolEntry(C, Offset));
+ Constants.push_back(MachineConstantPoolEntry(C, Alignment));
return Constants.size()-1;
}
// Check to see if we already have this constant.
//
// FIXME, this could be made much more efficient for large constant pools.
- unsigned AlignMask = (1 << Alignment)-1;
int Idx = V->getExistingMachineCPValue(this, Alignment);
if (Idx != -1)
return (unsigned)Idx;
-
- unsigned Offset = 0;
- if (!Constants.empty()) {
- Offset = Constants.back().getOffset();
- Offset += TD->getABITypeSize(Constants.back().getType());
- Offset = (Offset+AlignMask)&~AlignMask;
- }
-
- Constants.push_back(MachineConstantPoolEntry(V, Offset));
+
+ Constants.push_back(MachineConstantPoolEntry(V, Alignment));
return Constants.size()-1;
}
Constants[i].Val.MachineCPVal->print(OS);
else
OS << *(Value*)Constants[i].Val.ConstVal;
- OS << " , offset=" << Constants[i].getOffset();
+ OS << " , alignment=" << Constants[i].getAlignment();
OS << "\n";
}
}
-void MachineConstantPool::dump() const { print(errs()); errs().flush(); }
+void MachineConstantPool::dump() const { print(errs()); }