llvm.org GIT mirror llvm / 71f3b94
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 Rafael Espindola 13 years ago
5 changed file(s) with 89 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
7676
7777 FunctionPass *createARMISelDag(TargetMachine &TM);
7878 FunctionPass *createARMCodePrinterPass(std::ostream &OS, TargetMachine &TM);
79 FunctionPass *createARMFixMulPass();
7980 } // end namespace llvm;
8081
8182 // Defines symbolic names for ARM registers. This defines a mapping from
0 //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the "Instituto Nokia de Tecnologia" and
5 // is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //
11 //===----------------------------------------------------------------------===//
12
13
14 #include "ARM.h"
15 #include "llvm/CodeGen/MachineInstrBuilder.h"
16 #include "llvm/CodeGen/MachineFunctionPass.h"
17 #include "llvm/Support/Compiler.h"
18
19 using namespace llvm;
20
21 namespace {
22 class VISIBILITY_HIDDEN FixMul : public MachineFunctionPass {
23 virtual bool runOnMachineFunction(MachineFunction &MF);
24 };
25 }
26
27 FunctionPass *llvm::createARMFixMulPass() { return new FixMul(); }
28
29 bool FixMul::runOnMachineFunction(MachineFunction &MF) {
30 bool Changed = false;
31
32 for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
33 BB != E; ++BB) {
34 MachineBasicBlock &MBB = *BB;
35
36 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
37 I != E; ++I) {
38 MachineInstr *MI = I;
39
40 if (MI->getOpcode() == ARM::MUL) {
41 MachineOperand &RdOp = MI->getOperand(0);
42 MachineOperand &RmOp = MI->getOperand(1);
43 MachineOperand &RsOp = MI->getOperand(2);
44
45 unsigned Rd = RdOp.getReg();
46 unsigned Rm = RmOp.getReg();
47 unsigned Rs = RsOp.getReg();
48
49 if(Rd == Rm) {
50 Changed = true;
51 if (Rd != Rs) {
52 RmOp.setReg(Rs);
53 RsOp.setReg(Rm);
54 } else {
55 BuildMI(MBB, I, ARM::MOV, 3, ARM::R12).addReg(Rm).addImm(0)
56 .addImm(ARMShift::LSL);
57 RmOp.setReg(ARM::R12);
58 }
59 }
60 }
61 }
62 }
63
64 return Changed;
65 }
5353 PM.add(createARMISelDag(*this));
5454 return false;
5555 }
56
57 bool ARMTargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
58 PM.add(createARMFixMulPass());
59 return true;
60 }
61
5662 bool ARMTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
5763 std::ostream &Out) {
5864 // Output assembly language.
5965 PM.add(createARMCodePrinterPass(Out, *this));
6066 return false;
6167 }
62
4545
4646 // Pass Pipeline Configuration
4747 virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
48 virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast);
4849 virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
4950 std::ostream &Out);
5051 };
0 ; RUN: llvm-as < %s | llc -march=arm &&
1 ; RUN: llvm-as < %s | llc -march=arm | grep "mul r0, r12, r0" | wc -l | grep 1 &&
2 ; RUN: llvm-as < %s | llc -march=arm | grep "mul r0, r1, r0" | wc -l | grep 1
3
4 int %mul1(int %u) {
5 entry:
6 %tmp = mul int %u, %u;
7 ret int %tmp
8 }
9
10 int %mul2(int %u, int %v) {
11 entry:
12 %tmp = mul int %u, %v;
13 ret int %tmp
14 }