diff --git a/lib/Target/ARM/ARMExport.cpp b/lib/Target/ARM/ARMExport.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58cc116b5c0066ce192a5c306baf354240b22cfe --- /dev/null +++ b/lib/Target/ARM/ARMExport.cpp @@ -0,0 +1,176 @@ +//===-- ARMExport.cpp - Target-specific PML exporter for ARM --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a ARM-customized PML export driver and -pass. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "arm-export" + +#include "ARM.h" +#include "ARMInstrInfo.h" +#include "ARMMachineFunctionInfo.h" +#include "ARMTargetMachine.h" +#include "InstPrinter/ARMInstPrinter.h" +#include "llvm/IR/Function.h" +#include "llvm/CodeGen/Analysis.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/PMLExport.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + +#include <map> +#include <sstream> +#include <iostream> + +using namespace llvm; + +namespace llvm { + + class ARMMachineExport : public PMLMachineExport { + + public: + ARMMachineExport(ARMBaseTargetMachine &tm, ModulePass &mp, + PMLInstrInfo *PII) + : PMLMachineExport(tm, mp, PII) {} + + + virtual bool doExportInstruction(const MachineInstr *Ins) { + return true; + } + + virtual void serialize(MachineFunction &MF); + + }; + + + class ARMModuleExportPass : public PMLModuleExportPass { + static char ID; + + public: + ARMModuleExportPass(ARMBaseTargetMachine &tm, StringRef filename, + ArrayRef<std::string> roots) + : PMLModuleExportPass(ID, tm, filename, roots) + { + setPMLInstrInfo(new PMLInstrInfo()); + } + + virtual const char *getPassName() const { + return "ARM YAML/PML Module Export"; + } + + }; + + char ARMModuleExportPass::ID = 0; + + + /// createARMExportPass - Returns a new ARMExportPass + /// \see ARMExportPass + ModulePass *createARMModuleExportPass(ARMBaseTargetMachine &TM, + std::string& Filename, + std::string& BitcodeFilename, + ArrayRef<std::string> Roots) + { + ARMModuleExportPass *PEP = + new ARMModuleExportPass(TM, Filename, Roots); + + // Add our own export passes + PEP->addExporter( new PMLBitcodeExport(TM, *PEP) ); + PEP->addExporter( new PMLRelationGraphExport(TM, *PEP) ); + PEP->addExporter( new ARMMachineExport(TM, *PEP, PEP->getPMLInstrInfo())); + if (! BitcodeFilename.empty()) + PEP->writeBitcode(BitcodeFilename); + return PEP; + } + + void ARMMachineExport::serialize(MachineFunction &MF) + { + errs() << "foo\n"; + yaml::PMLDoc &YDoc = getPMLDoc(); + Function* F = const_cast<Function*>(MF.getFunction()); + MachineLoopInfo &MLI(P.getAnalysis<MachineLoopInfo>(*F)); + + yaml::MachineFunction *PMF = + new yaml::MachineFunction(MF.getFunctionNumber()); + + PMF->MapsTo = yaml::Name(MF.getFunction()->getName()); + PMF->Level = yaml::level_machinecode; + yaml::MachineBlock *B; + + // export argument-register mapping if available + exportArgumentRegisterMapping(PMF, MF); + + for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) + { + B = PMF->addBlock( + new yaml::MachineBlock(BB->getNumber())); + + for (MachineBasicBlock::const_pred_iterator BBPred = BB->pred_begin(), + E = BB->pred_end(); BBPred != E; ++BBPred) + B->Predecessors.push_back(yaml::Name((*BBPred)->getNumber())); + for (MachineBasicBlock::const_succ_iterator BBSucc = BB->succ_begin(), + E = BB->succ_end(); BBSucc != E; ++BBSucc) + B->Successors.push_back(yaml::Name((*BBSucc)->getNumber())); + + B->MapsTo = yaml::Name(BB->getName()); + + // export loop information + MachineLoop *Loop = MLI.getLoopFor(BB); + if (Loop && Loop->getHeader() == BB) { + exportLoopInfo(MF, YDoc, Loop); + errs() << "bar\n"; + } + while (Loop) { + B->Loops.push_back(yaml::Name(Loop->getHeader()->getNumber())); + Loop = Loop->getParentLoop(); + } + + unsigned Index = 0; + bool IsBundled = false; + for (MachineBasicBlock::instr_iterator Ins = BB->instr_begin(), + E = BB->instr_end(); Ins != E; ++Ins) + { + // check if this is the first instruction, only set to bundled once we + // exported at least one instruction from the bundle (skipping pseudos) + if (!Ins->isBundledWithPred()) { + IsBundled = false; + } + + if (!doExportInstruction(Ins)) { Index++; continue; } + + yaml::MachineInstruction *I = B->addInstruction( + new yaml::MachineInstruction(Index++)); + exportInstruction(MF, I, Ins, IsBundled); + + const LLVMContext &Ctx = MF.getFunction()->getContext(); + DebugLoc dl = Ins->getDebugLoc(); + B->setSrcLocOnce(dl, dl.getScope(Ctx)); + + IsBundled = true; + } + } + + exportSubfunctions(MF, PMF); + + // TODO: we do not compute a hash yet + PMF->Hash = StringRef("0"); + errs() << "baz\n"; + YDoc.addMachineFunction(PMF); + errs() << "baz\n"; + } + +} // end namespace llvm