blob: b41792330362fefdaadb81d9fa55a1093ad5a097 [file] [log] [blame]
Quentin Colombet8e8e85c2016-04-05 19:06:01 +00001//===- llvm/CodeGen/GlobalISel/RegBankSelect.cpp - RegBankSelect -*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file implements the RegBankSelect class.
11//===----------------------------------------------------------------------===//
12
13#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
Quentin Colombet40ad5732016-04-07 18:19:27 +000014#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
15#include "llvm/CodeGen/MachineRegisterInfo.h"
16#include "llvm/Target/TargetSubtargetInfo.h"
Quentin Colombet8e8e85c2016-04-05 19:06:01 +000017
18#define DEBUG_TYPE "regbankselect"
19
20using namespace llvm;
21
22char RegBankSelect::ID = 0;
23INITIALIZE_PASS(RegBankSelect, "regbankselect",
24 "Assign register bank of generic virtual registers",
25 false, false);
26
Quentin Colombet40ad5732016-04-07 18:19:27 +000027RegBankSelect::RegBankSelect()
28 : MachineFunctionPass(ID), RBI(nullptr), MRI(nullptr) {
Quentin Colombet8e8e85c2016-04-05 19:06:01 +000029 initializeRegBankSelectPass(*PassRegistry::getPassRegistry());
30}
31
Quentin Colombet40ad5732016-04-07 18:19:27 +000032void RegBankSelect::init(MachineFunction &MF) {
33 RBI = MF.getSubtarget().getRegBankInfo();
34 assert(RBI && "Cannot work without RegisterBankInfo");
35 MRI = &MF.getRegInfo();
36 MIRBuilder.setMF(MF);
37}
38
39bool RegBankSelect::assignmentMatch(
40 unsigned Reg, const RegisterBankInfo::ValueMapping &ValMapping) const {
41 // Each part of a break down needs to end up in a different register.
42 // In other word, Reg assignement does not match.
43 if (ValMapping.BreakDown.size() > 1)
44 return false;
45
46 const RegClassOrRegBank &CurAssignment = MRI->getRegClassOrRegBank(Reg);
47 // Nothing assigned, the assignment does not match.
48 if (!CurAssignment)
49 return false;
50 // Get the register bank form the current assignment.
51 const RegisterBank *CurRegBank = nullptr;
52 if (CurAssignment.is<const TargetRegisterClass *>())
53 CurRegBank = &RBI->getRegBankFromRegClass(
54 *CurAssignment.get<const TargetRegisterClass *>());
55 else
56 CurRegBank = CurAssignment.get<const RegisterBank *>();
57 return CurRegBank == ValMapping.BreakDown[0].RegBank;
58}
59
60unsigned
61RegBankSelect::repairReg(unsigned Reg,
62 const RegisterBankInfo::ValueMapping &ValMapping) {
63 assert(ValMapping.BreakDown.size() == 1 &&
64 "Support for complex break down not supported yet");
65 const RegisterBankInfo::PartialMapping &PartialMap = ValMapping.BreakDown[0];
66 assert(PartialMap.Mask.getBitWidth() == MRI->getSize(Reg) &&
67 "Repairing other than copy not implemented yet");
68 unsigned NewReg =
69 MRI->createGenericVirtualRegister(PartialMap.Mask.getBitWidth());
70 (void)MIRBuilder.buildInstr(TargetOpcode::COPY, NewReg, Reg);
71 return NewReg;
72}
73
74void RegBankSelect::assignInstr(MachineInstr &MI) {
75 const RegisterBankInfo::InstructionMapping DefaultMapping =
76 RBI->getInstrMapping(MI);
77 // Make sure the mapping is valid for MI.
78 DefaultMapping.verify(MI);
79 // Set the insertion point before MI.
80 // This is where we are going to insert the repairing code if any.
81 MIRBuilder.setInstr(MI, /*Before*/ true);
82
83 // For now, do not look for alternative mappings.
84 // Alternative mapping may require to rewrite MI and we do not support
85 // that yet.
86 // Walk the operands and assign then to the chosen mapping, possibly with
87 // the insertion of repair code for uses.
88 for (unsigned OpIdx = 0, EndIdx = MI.getNumOperands(); OpIdx != EndIdx;
89 ++OpIdx) {
90 MachineOperand &MO = MI.getOperand(OpIdx);
91 // Nothing to be done for non-register operands.
92 if (!MO.isReg())
93 continue;
94 unsigned Reg = MO.getReg();
95 if (!Reg)
96 continue;
97
98 const RegisterBankInfo::ValueMapping &ValMapping =
99 DefaultMapping.getOperandMapping(OpIdx);
100 // If Reg is already properly mapped, move on.
101 if (assignmentMatch(Reg, ValMapping))
102 continue;
103
104 // For uses, we may need to create a new temporary.
105 // Indeed, if Reg is already assigned a register bank, at this
106 // point, we know it is different from the one defined by the
107 // chosen mapping, we need to adjust for that.
108 assert(ValMapping.BreakDown.size() == 1 &&
109 "Support for complex break down not supported yet");
110 if (!MO.isDef() && MRI->getRegClassOrRegBank(Reg)) {
111 // For phis, we need to change the insertion point to the end of
112 // the related predecessor block.
113 assert(!MI.isPHI() && "PHI support not implemented yet");
114 Reg = repairReg(Reg, ValMapping);
115 }
116 // If we end up here, MO should be free of encoding constraints,
117 // i.e., we do not have to constrained the RegBank of Reg to
118 // the requirement of the operands.
119 // If that is not the case, this means the code was broken before
120 // hands because we should have found that the assignment match.
121 // This will not hold when we will consider alternative mappings.
122 MRI->setRegBank(Reg, *ValMapping.BreakDown[0].RegBank);
123 MO.setReg(Reg);
124 }
125}
126
Quentin Colombet8e8e85c2016-04-05 19:06:01 +0000127bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) {
Quentin Colombet40ad5732016-04-07 18:19:27 +0000128 init(MF);
129 // Walk the function and assign register banks to all operands.
130 for (MachineBasicBlock &MBB : MF)
131 for (MachineInstr &MI : MBB)
132 assignInstr(MI);
Quentin Colombet8e8e85c2016-04-05 19:06:01 +0000133 return false;
134}