1 //===-- SILowerLiteralConstants.cpp - Lower intrs using literal constants--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 // This pass performs the following transformation on instructions with
12 // %VGPR0 = V_MOV_IMM_I32 1
17 // * %VGPR = V_MOV_B32_32 SI_LITERAL_CONSTANT
18 // * SI_LOAD_LITERAL 1
20 // The resulting sequence matches exactly how the hardware handles immediate
21 // operands, so this transformation greatly simplifies the code generator.
23 // Only the *_MOV_IMM_* support immediate operands at the moment, but when
24 // support for immediate operands is added to other instructions, they
25 // will be lowered here as well.
26 //===----------------------------------------------------------------------===//
29 #include "llvm/CodeGen/MachineFunction.h"
30 #include "llvm/CodeGen/MachineFunctionPass.h"
31 #include "llvm/CodeGen/MachineInstrBuilder.h"
32 #include "llvm/CodeGen/MachineInstrBundle.h"
38 class SILowerLiteralConstantsPass
: public MachineFunctionPass
{
42 const TargetInstrInfo
*TII
;
45 SILowerLiteralConstantsPass(TargetMachine
&tm
) :
46 MachineFunctionPass(ID
), TII(tm
.getInstrInfo()) { }
48 virtual bool runOnMachineFunction(MachineFunction
&MF
);
50 const char *getPassName() const {
51 return "SI Lower literal constants pass";
55 } // End anonymous namespace
57 char SILowerLiteralConstantsPass::ID
= 0;
59 FunctionPass
*llvm::createSILowerLiteralConstantsPass(TargetMachine
&tm
) {
60 return new SILowerLiteralConstantsPass(tm
);
63 bool SILowerLiteralConstantsPass::runOnMachineFunction(MachineFunction
&MF
) {
64 for (MachineFunction::iterator BB
= MF
.begin(), BB_E
= MF
.end();
66 MachineBasicBlock
&MBB
= *BB
;
67 for (MachineBasicBlock::iterator I
= MBB
.begin(), Next
= llvm::next(I
);
68 I
!= MBB
.end(); I
= Next
, Next
= llvm::next(I
)) {
69 MachineInstr
&MI
= *I
;
70 switch (MI
.getOpcode()) {
72 case AMDGPU::S_MOV_IMM_I32
:
73 case AMDGPU::S_MOV_IMM_I64
:
74 case AMDGPU::V_MOV_IMM_F32
:
75 case AMDGPU::V_MOV_IMM_I32
: {
77 unsigned LoadLiteralOpcode
;
78 MachineOperand LiteralOp
= MI
.getOperand(1);
79 if (AMDGPU::VReg_32RegClass
.contains(MI
.getOperand(0).getReg())) {
80 MovOpcode
= AMDGPU::V_MOV_B32_e32
;
82 MovOpcode
= AMDGPU::S_MOV_B32
;
84 if (LiteralOp
.isImm()) {
85 LoadLiteralOpcode
= AMDGPU::SI_LOAD_LITERAL_I32
;
87 LoadLiteralOpcode
= AMDGPU::SI_LOAD_LITERAL_F32
;
90 BuildMI(MBB
, I
, MBB
.findDebugLoc(I
), TII
->get(MovOpcode
),
91 MI
.getOperand(0).getReg())
92 .addReg(AMDGPU::SI_LITERAL_CONSTANT
);
94 BuildMI(MBB
, I
, MBB
.findDebugLoc(I
), TII
->get(LoadLiteralOpcode
))
95 .addOperand(MI
.getOperand(1));
96 Last
->setIsInsideBundle();
97 llvm::finalizeBundle(MBB
, First
, Last
);