aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2006-09-19 15:49:25 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2006-09-19 15:49:25 +0000
commit71f3b94fa846114a2ce45645ef262e230737e65e (patch)
tree676e649f423f75cd8af53112cf4c24bf371ba7ae
parentd0b9983d27d1b6c4ca9996b69a9161773d39dfeb (diff)
Implement a MachineFunctionPass to fix the mul instruction
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30485 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARM.h1
-rw-r--r--lib/Target/ARM/ARMMul.cpp66
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp7
-rw-r--r--lib/Target/ARM/ARMTargetMachine.h1
-rw-r--r--test/CodeGen/ARM/mul.ll15
5 files changed, 89 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h
index ca84634bed..49ed64dca5 100644
--- a/lib/Target/ARM/ARM.h
+++ b/lib/Target/ARM/ARM.h
@@ -77,6 +77,7 @@ namespace llvm {
FunctionPass *createARMISelDag(TargetMachine &TM);
FunctionPass *createARMCodePrinterPass(std::ostream &OS, TargetMachine &TM);
+ FunctionPass *createARMFixMulPass();
} // end namespace llvm;
// Defines symbolic names for ARM registers. This defines a mapping from
diff --git a/lib/Target/ARM/ARMMul.cpp b/lib/Target/ARM/ARMMul.cpp
new file mode 100644
index 0000000000..b984e7dc5c
--- /dev/null
+++ b/lib/Target/ARM/ARMMul.cpp
@@ -0,0 +1,66 @@
+//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the "Instituto Nokia de Tecnologia" and
+// is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "ARM.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/Compiler.h"
+
+using namespace llvm;
+
+namespace {
+ class VISIBILITY_HIDDEN FixMul : public MachineFunctionPass {
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+ };
+}
+
+FunctionPass *llvm::createARMFixMulPass() { return new FixMul(); }
+
+bool FixMul::runOnMachineFunction(MachineFunction &MF) {
+ bool Changed = false;
+
+ for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
+ BB != E; ++BB) {
+ MachineBasicBlock &MBB = *BB;
+
+ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
+ I != E; ++I) {
+ MachineInstr *MI = I;
+
+ if (MI->getOpcode() == ARM::MUL) {
+ MachineOperand &RdOp = MI->getOperand(0);
+ MachineOperand &RmOp = MI->getOperand(1);
+ MachineOperand &RsOp = MI->getOperand(2);
+
+ unsigned Rd = RdOp.getReg();
+ unsigned Rm = RmOp.getReg();
+ unsigned Rs = RsOp.getReg();
+
+ if(Rd == Rm) {
+ Changed = true;
+ if (Rd != Rs) {
+ RmOp.setReg(Rs);
+ RsOp.setReg(Rm);
+ } else {
+ BuildMI(MBB, I, ARM::MOV, 3, ARM::R12).addReg(Rm).addImm(0)
+ .addImm(ARMShift::LSL);
+ RmOp.setReg(ARM::R12);
+ }
+ }
+ }
+ }
+ }
+
+ return Changed;
+}
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index ccf0fb7ed6..7506ea8c29 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -54,10 +54,15 @@ bool ARMTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createARMISelDag(*this));
return false;
}
+
+bool ARMTargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
+ PM.add(createARMFixMulPass());
+ return true;
+}
+
bool ARMTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
std::ostream &Out) {
// Output assembly language.
PM.add(createARMCodePrinterPass(Out, *this));
return false;
}
-
diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h
index b453f0b647..b9a3d9809d 100644
--- a/lib/Target/ARM/ARMTargetMachine.h
+++ b/lib/Target/ARM/ARMTargetMachine.h
@@ -46,6 +46,7 @@ public:
// Pass Pipeline Configuration
virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast);
virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
std::ostream &Out);
};
diff --git a/test/CodeGen/ARM/mul.ll b/test/CodeGen/ARM/mul.ll
new file mode 100644
index 0000000000..77f94f087f
--- /dev/null
+++ b/test/CodeGen/ARM/mul.ll
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | llc -march=arm &&
+; RUN: llvm-as < %s | llc -march=arm | grep "mul r0, r12, r0" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -march=arm | grep "mul r0, r1, r0" | wc -l | grep 1
+
+int %mul1(int %u) {
+entry:
+ %tmp = mul int %u, %u;
+ ret int %tmp
+}
+
+int %mul2(int %u, int %v) {
+entry:
+ %tmp = mul int %u, %v;
+ ret int %tmp
+}