Skip to content

Commit b4e7118

Browse files
author
Quentin Colombet
committed
[GlobalISel] Refactor the logic to constraint registers.
Move the logic to constraint register from InstructionSelector to a utility function. It will be required by other passes in the GlobalISel pipeline. llvm-svn: 290374
1 parent 37db58e commit b4e7118

File tree

4 files changed

+96
-12
lines changed

4 files changed

+96
-12
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//==-- llvm/CodeGen/GlobalISel/Utils.h ---------------------------*- 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+
//
10+
/// \file This file declares the API of helper functions used throughout the
11+
/// GlobalISel pipeline.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_CODEGEN_GLOBALISEL_UTILS_H
16+
#define LLVM_CODEGEN_GLOBALISEL_UTILS_H
17+
18+
namespace llvm {
19+
20+
class MachineFunction;
21+
class MachineInstr;
22+
class MachineRegisterInfo;
23+
class MCInstrDesc;
24+
class RegisterBankInfo;
25+
class TargetInstrInfo;
26+
class TargetRegisterInfo;
27+
28+
/// Try to constrain Reg so that it is usable by argument OpIdx of the
29+
/// provided MCInstrDesc \p II. If this fails, create a new virtual
30+
/// register in the correct class and insert a COPY before \p InsertPt.
31+
/// The debug location of \p InsertPt is used for the new copy.
32+
///
33+
/// \return The virtual register constrained to the right register class.
34+
unsigned constrainOperandRegClass(const MachineFunction &MF,
35+
const TargetRegisterInfo &TRI,
36+
MachineRegisterInfo &MRI,
37+
const TargetInstrInfo &TII,
38+
const RegisterBankInfo &RBI,
39+
MachineInstr &InsertPt, const MCInstrDesc &II,
40+
unsigned Reg, unsigned OpIdx);
41+
42+
} // End namespace llvm.
43+
#endif

llvm/lib/CodeGen/GlobalISel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ set(GLOBAL_ISEL_FILES
1111
RegBankSelect.cpp
1212
RegisterBank.cpp
1313
RegisterBankInfo.cpp
14+
Utils.cpp
1415
)
1516

1617
# Add GlobalISel files to the dependencies if the user wants to build it.

llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
1414
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
15+
#include "llvm/CodeGen/GlobalISel/Utils.h"
1516
#include "llvm/CodeGen/MachineInstr.h"
1617
#include "llvm/Target/TargetInstrInfo.h"
1718
#include "llvm/Target/TargetRegisterInfo.h"
@@ -39,27 +40,21 @@ bool InstructionSelector::constrainSelectedInstRegOperands(
3940
DEBUG(dbgs() << "Converting operand: " << MO << '\n');
4041
assert(MO.isReg() && "Unsupported non-reg operand");
4142

43+
unsigned Reg = MO.getReg();
4244
// Physical registers don't need to be constrained.
43-
if (TRI.isPhysicalRegister(MO.getReg()))
45+
if (TRI.isPhysicalRegister(Reg))
4446
continue;
4547

4648
// Register operands with a value of 0 (e.g. predicate operands) don't need
4749
// to be constrained.
48-
if (MO.getReg() == 0)
50+
if (Reg == 0)
4951
continue;
5052

51-
const TargetRegisterClass *RC = TII.getRegClass(I.getDesc(), OpI, &TRI, MF);
52-
assert(RC && "Selected inst should have regclass operand");
53-
5453
// If the operand is a vreg, we should constrain its regclass, and only
5554
// insert COPYs if that's impossible.
56-
// If the operand is a physreg, we only insert COPYs if the register class
57-
// doesn't contain the register.
58-
if (RBI.constrainGenericRegister(MO.getReg(), *RC, MRI))
59-
continue;
60-
61-
DEBUG(dbgs() << "Constraining with COPYs isn't implemented yet");
62-
return false;
55+
// constrainOperandRegClass does that for us.
56+
MO.setReg(constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(),
57+
Reg, OpI));
6358
}
6459
return true;
6560
}

llvm/lib/CodeGen/GlobalISel/Utils.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===- llvm/CodeGen/GlobalISel/Utils.cpp -------------------------*- 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 This file implements the utility functions used by the GlobalISel
10+
/// pipeline.
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/CodeGen/GlobalISel/Utils.h"
14+
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
15+
#include "llvm/CodeGen/MachineInstr.h"
16+
#include "llvm/CodeGen/MachineInstrBuilder.h"
17+
#include "llvm/CodeGen/MachineRegisterInfo.h"
18+
#include "llvm/Target/TargetInstrInfo.h"
19+
#include "llvm/Target/TargetRegisterInfo.h"
20+
21+
#define DEBUG_TYPE "globalisel-utils"
22+
23+
using namespace llvm;
24+
25+
unsigned llvm::constrainOperandRegClass(
26+
const MachineFunction &MF, const TargetRegisterInfo &TRI,
27+
MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
28+
const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II,
29+
unsigned Reg, unsigned OpIdx) {
30+
// Assume physical registers are properly constrained.
31+
assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
32+
"PhysReg not implemented");
33+
34+
const TargetRegisterClass *RegClass = TII.getRegClass(II, OpIdx, &TRI, MF);
35+
36+
if (!RBI.constrainGenericRegister(Reg, *RegClass, MRI)) {
37+
unsigned NewReg = MRI.createVirtualRegister(RegClass);
38+
BuildMI(*InsertPt.getParent(), InsertPt, InsertPt.getDebugLoc(),
39+
TII.get(TargetOpcode::COPY), NewReg)
40+
.addReg(Reg);
41+
return NewReg;
42+
}
43+
44+
return Reg;
45+
}

0 commit comments

Comments
 (0)