From 17c494b91c19111df0a7a279f60f41a91fb9ce8e Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Thu, 11 Feb 2016 17:51:31 +0000 Subject: [PATCH] [GlobalISel][IRTranslator] Teach the pass how to translate Add instructions. llvm-svn: 260549 --- .../include/llvm/CodeGen/GlobalISel/IRTranslator.h | 17 +++++++- llvm/include/llvm/CodeGen/GlobalISel/Types.h | 4 +- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 45 +++++++++++++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 75e14cf..bae56f5 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -20,16 +20,20 @@ #define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H #include "Types.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/IR/Constants.h" namespace llvm { // Forward declarations. +class BasicBlock; class Constant; class Instruction; +class MachineBasicBlock; +class MachineFunction; class MachineInstr; class MachineIRBuilder; +class MachineRegisterInfo; // Technically the pass should run on an hypothetical MachineModule, // since it should translate Global into some sort of MachineGlobal. @@ -63,6 +67,8 @@ private: // do not appear in that map. SmallSetVector Constants; + DenseMap BBToMBB; + /* A bunch of methods targeting ADD, SUB, etc. */ // Return true if the translation was successful, false // otherwise. @@ -92,6 +98,9 @@ private: // IRBuilder, but for Machine IR. MachineIRBuilder *MIRBuilder; + /// MachineRegisterInfo used to create virtual registers. + MachineRegisterInfo *MRI; + // Return true if the translation from LLVM IR to Machine IR // suceeded. // See translateXXX for details. @@ -102,6 +111,12 @@ private: // of each constant depending on how fancy we want to be. // * Clear the different maps. void finalize(); + + /// Get the sequence of VRegs for that \p Val. + const VRegsSequence &getOrCreateVRegs(const Value *Val); + + MachineBasicBlock &getOrCreateBB(const BasicBlock *BB); + public: // Ctor, nothing fancy. IRTranslator(); diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Types.h b/llvm/include/llvm/CodeGen/GlobalISel/Types.h index 5e10919..9892a79 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/Types.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/Types.h @@ -21,6 +21,8 @@ namespace llvm { +typedef SmallVector VRegsSequence; + /// Map a value to virtual registers. /// We must support several virtual registers for a value. /// Indeed each virtual register is mapped to one EVT, but a value @@ -28,7 +30,7 @@ namespace llvm { /// In that case the value will be break into EVTs. /// Note: We need to expose this type to the target hooks for thing like /// ABI lowering that would be used during IRTranslation. -typedef DenseMap> ValueToVRegs; +typedef DenseMap ValueToVRegs; } // End namespace llvm. #endif diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 704b019..e10338d 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -12,8 +12,13 @@ #include "llvm/CodeGen/GlobalISel/IRTranslator.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/Constant.h" #include "llvm/IR/Function.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" #define DEBUG_TYPE "irtranslator" @@ -21,15 +26,49 @@ using namespace llvm; char IRTranslator::ID = 0; +const VRegsSequence &IRTranslator::getOrCreateVRegs(const Value *Val) { + VRegsSequence &ValRegSequence = ValToVRegs[Val]; + // Check if this is the first time we see Val. + if (ValRegSequence.empty()) { + // Fill ValRegsSequence with the sequence of registers + // we need to concat together to produce the value. + assert(Val->getType()->isSized() && + "Don't know how to create an empty vreg"); + assert(!Val->getType()->isAggregateType() && "Not yet implemented"); + unsigned Size = Val->getType()->getPrimitiveSizeInBits(); + unsigned VReg = MRI->createGenericVirtualRegister(Size); + ValRegSequence.push_back(VReg); + assert(isa(Val) && "Not yet implemented"); + } + assert(ValRegSequence.size() == 1 && + "We support only one vreg per value at the moment"); + return ValRegSequence; +} + +MachineBasicBlock &IRTranslator::getOrCreateBB(const BasicBlock *BB) { + MachineBasicBlock *&MBB = BBToMBB[BB]; + if (!MBB) { + MachineFunction &MF = MIRBuilder->getMF(); + MBB = MF.CreateMachineBasicBlock(); + MF.push_back(MBB); + } + return *MBB; +} + bool IRTranslator::translateADD(const Instruction &Inst) { // Get or create a virtual register for each value. // Unless the value is a Constant => loadimm cst? // or inline constant each time? // Creation of a virtual register needs to have a size. - return false; + unsigned Op0 = *getOrCreateVRegs(Inst.getOperand(0)).begin(); + unsigned Op1 = *getOrCreateVRegs(Inst.getOperand(1)).begin(); + unsigned Res = *getOrCreateVRegs(&Inst).begin(); + MIRBuilder->buildInstr(TargetOpcode::G_ADD, Res, Op0, Op1); + return true; } bool IRTranslator::translate(const Instruction &Inst) { + MIRBuilder->setDebugLoc(Inst.getDebugLoc()); switch(Inst.getOpcode()) { case Instruction::Add: { return translateADD(Inst); @@ -53,7 +92,11 @@ IRTranslator::IRTranslator() bool IRTranslator::runOnMachineFunction(MachineFunction &MF) { const Function &F = *MF.getFunction(); + MIRBuilder->setFunction(MF); + MRI = &MF.getRegInfo(); for (const BasicBlock &BB: F) { + MachineBasicBlock &MBB = getOrCreateBB(&BB); + MIRBuilder->setBasicBlock(MBB); for (const Instruction &Inst: BB) { bool Succeeded = translate(Inst); if (!Succeeded) { -- 2.7.4