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 //===----------------------------------------------------------------------===//
11 /// \brief This pass performs the following transformation on instructions with
12 /// literal constants:
14 /// %VGPR0 = V_MOV_IMM_I32 1
19 /// * %VGPR = V_MOV_B32_32 SI_LITERAL_CONSTANT
20 /// * SI_LOAD_LITERAL 1
22 /// The resulting sequence matches exactly how the hardware handles immediate
23 /// operands, so this transformation greatly simplifies the code generator.
25 /// Only the *_MOV_IMM_* support immediate operands at the moment, but when
26 /// support for immediate operands is added to other instructions, they
27 /// will be lowered here as well.
28 //===----------------------------------------------------------------------===//
31 #include "llvm/CodeGen/MachineFunction.h"
32 #include "llvm/CodeGen/MachineFunctionPass.h"
33 #include "llvm/CodeGen/MachineInstrBuilder.h"
34 #include "llvm/CodeGen/MachineInstrBundle.h"
40 class SILowerLiteralConstantsPass : public MachineFunctionPass {
44 const TargetInstrInfo *TII;
47 SILowerLiteralConstantsPass(TargetMachine &tm) :
48 MachineFunctionPass(ID), TII(tm.getInstrInfo()) { }
50 virtual bool runOnMachineFunction(MachineFunction &MF);
52 const char *getPassName() const {
53 return "SI Lower literal constants pass";
57 } // End anonymous namespace
59 char SILowerLiteralConstantsPass::ID = 0;
61 FunctionPass *llvm::createSILowerLiteralConstantsPass(TargetMachine &tm) {
62 return new SILowerLiteralConstantsPass(tm);
65 bool SILowerLiteralConstantsPass::runOnMachineFunction(MachineFunction &MF) {
66 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
68 MachineBasicBlock &MBB = *BB;
69 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
70 I != MBB.end(); I = Next) {
72 MachineInstr &MI = *I;
73 switch (MI.getOpcode()) {
75 case AMDGPU::S_MOV_IMM_I32:
76 case AMDGPU::S_MOV_IMM_I64:
77 case AMDGPU::V_MOV_IMM_F32:
78 case AMDGPU::V_MOV_IMM_I32: {
80 unsigned LoadLiteralOpcode;
81 MachineOperand LiteralOp = MI.getOperand(1);
82 if (AMDGPU::VReg_32RegClass.contains(MI.getOperand(0).getReg())) {
83 MovOpcode = AMDGPU::V_MOV_B32_e32;
85 MovOpcode = AMDGPU::S_MOV_B32;
87 if (LiteralOp.isImm()) {
88 LoadLiteralOpcode = AMDGPU::SI_LOAD_LITERAL_I32;
90 LoadLiteralOpcode = AMDGPU::SI_LOAD_LITERAL_F32;
92 MIBundleBuilder Bundle(MBB, I);
94 .append(BuildMI(MF, MBB.findDebugLoc(I), TII->get(MovOpcode),
95 MI.getOperand(0).getReg())
96 .addReg(AMDGPU::SI_LITERAL_CONSTANT))
97 .append(BuildMI(MF, MBB.findDebugLoc(I),
98 TII->get(LoadLiteralOpcode))
99 .addOperand(MI.getOperand(1)));
100 llvm::finalizeBundle(MBB, Bundle.begin());
101 MI.eraseFromParent();