summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/radeon/AMDILLiteralManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeon/AMDILLiteralManager.cpp')
-rw-r--r--src/gallium/drivers/radeon/AMDILLiteralManager.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeon/AMDILLiteralManager.cpp b/src/gallium/drivers/radeon/AMDILLiteralManager.cpp
new file mode 100644
index 00000000000..43167f57001
--- /dev/null
+++ b/src/gallium/drivers/radeon/AMDILLiteralManager.cpp
@@ -0,0 +1,128 @@
+//===--- AMDILLiteralManager.cpp - AMDIL Literal Manager Pass --*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//==-----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "literal_manager"
+
+#include "AMDIL.h"
+
+#include "AMDILAlgorithms.tpp"
+#include "AMDILKernelManager.h"
+#include "AMDILMachineFunctionInfo.h"
+#include "AMDILSubtarget.h"
+#include "AMDILTargetMachine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetMachine.h"
+
+using namespace llvm;
+
+
+// AMDIL Literal Manager traverses through all of the LOADCONST instructions and
+// converts them from an immediate value to the literal index. The literal index
+// is valid IL, but the immediate values are not. The Immediate values must be
+// aggregated and declared for clarity and to reduce the number of literals that
+// are used. It is also illegal to declare the same literal twice, so this keeps
+// that from occuring.
+
+namespace {
+ class AMDILLiteralManager : public MachineFunctionPass {
+ public:
+ static char ID;
+ AMDILLiteralManager(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
+ virtual const char *getPassName() const;
+
+ bool runOnMachineFunction(MachineFunction &MF);
+ private:
+ bool trackLiterals(MachineBasicBlock::iterator *bbb);
+ TargetMachine &TM;
+ const AMDILSubtarget *mSTM;
+ AMDILKernelManager *mKM;
+ AMDILMachineFunctionInfo *mMFI;
+ int32_t mLitIdx;
+ bool mChanged;
+ };
+ char AMDILLiteralManager::ID = 0;
+}
+
+namespace llvm {
+ FunctionPass *
+ createAMDILLiteralManager(TargetMachine &tm AMDIL_OPT_LEVEL_DECL) {
+ return new AMDILLiteralManager(tm AMDIL_OPT_LEVEL_VAR);
+ }
+
+}
+
+AMDILLiteralManager::AMDILLiteralManager(TargetMachine &tm
+ AMDIL_OPT_LEVEL_DECL)
+ : MachineFunctionPass(ID),
+ TM(tm) {
+}
+
+bool AMDILLiteralManager::runOnMachineFunction(MachineFunction &MF) {
+ mChanged = false;
+ mMFI = MF.getInfo<AMDILMachineFunctionInfo>();
+ const AMDILTargetMachine *amdtm =
+ reinterpret_cast<const AMDILTargetMachine *>(&TM);
+ mSTM = dynamic_cast<const AMDILSubtarget *>(amdtm->getSubtargetImpl());
+ mKM = const_cast<AMDILKernelManager *>(mSTM->getKernelManager());
+ safeNestedForEach(MF.begin(), MF.end(), MF.begin()->begin(),
+ std::bind1st(std::mem_fun(&AMDILLiteralManager::trackLiterals), this));
+ return mChanged;
+}
+
+bool AMDILLiteralManager::trackLiterals(MachineBasicBlock::iterator *bbb) {
+ MachineInstr *MI = *bbb;
+ uint32_t Opcode = MI->getOpcode();
+ switch(Opcode) {
+ default:
+ return false;
+ case AMDIL::LOADCONST_i8:
+ case AMDIL::LOADCONST_i16:
+ case AMDIL::LOADCONST_i32:
+ case AMDIL::LOADCONST_i64:
+ case AMDIL::LOADCONST_f32:
+ case AMDIL::LOADCONST_f64:
+ break;
+ };
+ MachineOperand &dstOp = MI->getOperand(0);
+ MachineOperand &litOp = MI->getOperand(1);
+ if (!litOp.isImm() && !litOp.isFPImm()) {
+ return false;
+ }
+ if (!dstOp.isReg()) {
+ return false;
+ }
+ // Change the literal to the correct index for each literal that is found.
+ if (litOp.isImm()) {
+ int64_t immVal = litOp.getImm();
+ uint32_t idx = MI->getOpcode() == AMDIL::LOADCONST_i64
+ ? mMFI->addi64Literal(immVal)
+ : mMFI->addi32Literal(static_cast<int>(immVal), Opcode);
+ litOp.ChangeToImmediate(idx);
+ return false;
+ }
+
+ if (litOp.isFPImm()) {
+ const ConstantFP *fpVal = litOp.getFPImm();
+ uint32_t idx = MI->getOpcode() == AMDIL::LOADCONST_f64
+ ? mMFI->addf64Literal(fpVal)
+ : mMFI->addf32Literal(fpVal);
+ litOp.ChangeToImmediate(idx);
+ return false;
+ }
+
+ return false;
+}
+
+const char* AMDILLiteralManager::getPassName() const {
+ return "AMDIL Constant Propagation";
+}
+
+