Skip to content

Commit

Permalink
[MSP430] Optimize addressing mode 0(rn) -> @rn
Browse files Browse the repository at this point in the history
  • Loading branch information
chbessonova committed Dec 20, 2018
1 parent f4e0441 commit 7f3ec90
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/llvm/lib/Target/MSP430/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ tablegen(LLVM MSP430GenSubtargetInfo.inc -gen-subtarget)
add_public_tablegen_target(MSP430CommonTableGen)

add_llvm_target(MSP430CodeGen
MSP430AddressModeTransformPass.cpp
MSP430BranchSelector.cpp
MSP430ISelDAGToDAG.cpp
MSP430ISelLowering.cpp
Expand Down
1 change: 1 addition & 0 deletions src/llvm/lib/Target/MSP430/MSP430.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace llvm {
CodeGenOpt::Level OptLevel);

FunctionPass *createMSP430BranchSelectionPass();
FunctionPass *createMSP430AddrModeTransformPass();

} // end namespace llvm;

Expand Down
139 changes: 139 additions & 0 deletions src/llvm/lib/Target/MSP430/MSP430AddressModeTransformPass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
//===-- MSP430AddressModeTransformPass.cpp - MSP430 optimization pass ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The pass implements indexed (with 0 displacement) to indirect register
// addressing modes transformation.
//
//===----------------------------------------------------------------------===//

#include "MSP430.h"
#include "MSP430InstrInfo.h"
#include "MSP430Subtarget.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

#define DEBUG_TYPE "msp430-addr-mode-transform"

namespace {
class MSP430AddrModeTransform : public MachineFunctionPass {
public:
static char ID;
MSP430AddrModeTransform() : MachineFunctionPass(ID) {}

bool runOnMachineFunction(MachineFunction &MF) override;

StringRef getPassName() const override {
return "MSP430 indexed to indirect register addressing mode transformation";
}
};
char MSP430AddrModeTransform::ID = 0;
}

FunctionPass *llvm::createMSP430AddrModeTransformPass() {
return new MSP430AddrModeTransform();
}

static unsigned getSrcDispIdx(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case MSP430::RRA8m:
case MSP430::RRA16m:
case MSP430::CALLm:
case MSP430::SEXT16m:
case MSP430::SWPB16m:
return 1; // Single operand instructions
case MSP430::MOV8rm:
case MSP430::MOV16rm:
case MSP430::CMP8rm:
case MSP430::CMP16rm:
return 2; // Special case binary operands instructions
// $r12 = MOV16rm $r13, 0 :: (load 2 from %ir.i)
default:
return 3; // Common case binary operands instructions
}
}

static llvm::Optional<unsigned> getIndRegInstForm(const MachineInstr &MI) {
switch (MI.getOpcode()) {
#define CASE_BINOP(Name) \
case MSP430::Name##8rm : return MSP430::Name##8rn; \
case MSP430::Name##16rm : return MSP430::Name##16rn; \
case MSP430::Name##8mm : return MSP430::Name##8mn; \
case MSP430::Name##16mm : return MSP430::Name##16mn;

CASE_BINOP(MOV)
CASE_BINOP(ADD)
CASE_BINOP(AND)
CASE_BINOP(BIS)
CASE_BINOP(BIC)
CASE_BINOP(XOR)
CASE_BINOP(SUB)
CASE_BINOP(CMP)

#undef CASE_BINOP
#define CASE_SINGLOP(Name, Bits) \
case MSP430::Name##Bits##m : return MSP430::Name##Bits##n;

CASE_SINGLOP(RRA, 8)
CASE_SINGLOP(RRA, 16)
// TODO: RRC8m, RRC16m and CALLm aren't generated
// CASE_SINGLOP(RRC, 8)
// CASE_SINGLOP(RRC, 16)
// CASE_SINGLOP(CALL, )
CASE_SINGLOP(SEXT, 16)
CASE_SINGLOP(SWPB, 16)

#undef CASE_SINGLEOP

default:
return None;
}
}

static MachineInstr *tryTransformToIndReg(MachineInstr &MI,
unsigned IndRegOpc,
const TargetInstrInfo *TII) {
unsigned SrcDispIdx = getSrcDispIdx(MI);
auto &SrcDispOp = MI.getOperand(SrcDispIdx);

if (!SrcDispOp.isImm() || SrcDispOp.getImm() != 0)
return nullptr; // Transform is valid only for 0(rn) case

auto NewMI =
BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(IndRegOpc));

for (const auto &MO : MI.operands()) {
if (MI.getOperandNo(&MO) == SrcDispIdx)
continue; // Skip displacement for src operand
NewMI.add(MO);
}
return NewMI;
}

bool MSP430AddrModeTransform::runOnMachineFunction(MachineFunction &MF) {
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
bool MadeChange = false;

for (auto MBB = MF.begin(), E = MF.end(); MBB != E; ++MBB) {
for (auto MI = MBB->begin(), EE = MBB->end(); MI != EE; ++MI) {

if (Optional<unsigned> IndRegOpc = getIndRegInstForm(*MI)) {
if (auto *NewMI = tryTransformToIndReg(*MI, *IndRegOpc, TII)) {
MachineInstr *OldMI = &*MI;
MI = NewMI;
OldMI->eraseFromParent();
MadeChange |= true;
}
}
}
}
return MadeChange;
}
1 change: 1 addition & 0 deletions src/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ bool MSP430PassConfig::addInstSelector() {
}

void MSP430PassConfig::addPreEmitPass() {
addPass(createMSP430AddrModeTransformPass(), false);
// Must run branch selection immediately preceding the asm printer.
addPass(createMSP430BranchSelectionPass(), false);
}
125 changes: 125 additions & 0 deletions src/llvm/test/CodeGen/MSP430/indreg.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
; RUN: llc < %s -march=msp430 | FileCheck %s
target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:32"
target triple = "msp430-generic-generic"

define i16 @bisrn(i16 %x, i16* %a) nounwind {
; CHECK-LABEL: bisrn:
; CHECK: bis @r13, r12
%1 = load i16, i16* %a
%2 = or i16 %1,%x
ret i16 %2
}
define void @bismn(i16* %x, i16* %a) nounwind {
; CHECK-LABEL: bismn:
; CHECK: bis @r13, @r12
%1 = load i16, i16* %x
%2 = load i16, i16* %a
%3 = or i16 %1,%2
store i16 %3, i16* %x, align 2
ret void
}

define i16 @movrn(i16* %g, i16* %i) {
entry:
; CHECK-LABEL: movrn:
; CHECK: mov @r13, r12
%0 = load i16, i16* %i, align 2
ret i16 %0
}
define void @movmn(i16* %g, i16* %i) {
entry:
; CHECK-LABEL: movmn:
; CHECK: mov @r13, @r12
%0 = load i16, i16* %i, align 2
store i16 %0, i16* %g, align 2
ret void
}

define i16 @addrn(i16 %x, i16* %a) nounwind {
; CHECK-LABEL: addrn:
; CHECK: add @r13, r12
%1 = load i16, i16* %a
%2 = add i16 %1,%x
ret i16 %2
}
define void @addmn(i16* %x, i16* %a) nounwind {
; CHECK-LABEL: addmn:
; CHECK: add @r13, @r12
%1 = load i16, i16* %x
%2 = load i16, i16* %a
%3 = add i16 %2, %1
store i16 %3, i16* %x
ret void
}

define i16 @andrn(i16 %x, i16* %a) nounwind {
; CHECK-LABEL: andrn:
; CHECK: and @r13, r12
%1 = load i16, i16* %a
%2 = and i16 %1,%x
ret i16 %2
}
define void @andmn(i16* %x, i16* %a) nounwind {
; CHECK-LABEL: andmn:
; CHECK: and @r13, @r12
%1 = load i16, i16* %x
%2 = load i16, i16* %a
%3 = and i16 %2, %1
store i16 %3, i16* %x
ret void
}

define i16 @xorrn(i16 %x, i16* %a) nounwind {
; CHECK-LABEL: xorrn:
; CHECK: xor @r13, r12
%1 = load i16, i16* %a
%2 = xor i16 %1,%x
ret i16 %2
}
define void @xormn(i16* %x, i16* %a) nounwind {
; CHECK-LABEL: xormn:
; CHECK: xor @r13, @r12
%1 = load i16, i16* %x
%2 = load i16, i16* %a
%3 = xor i16 %2, %1
store i16 %3, i16* %x
ret void
}

define void @cmpmn(i16* %g, i16* %i) {
entry:
; CHECK-LABEL: cmpmn:
; CHECK: cmp @r12, @r13
%0 = load i16, i16* %g, align 2
%1 = load i16, i16* %i, align 2
%cmp = icmp sgt i16 %0, %1
br i1 %cmp, label %if.then, label %if.end

if.then: ; preds = %entry
store i16 0, i16* %g, align 2
br label %if.end

if.end: ; preds = %if.then, %entry
ret void
}

define void @rra16n(i16* %i) {
entry:
; CHECK-LABEL: rra16n:
; CHECK: rra @r12
%0 = load i16, i16* %i, align 2
%shr = ashr i16 %0, 1
store i16 %shr, i16* %i, align 2
ret void
}

define void @sxt16n(i16* %x) {
entry:
; CHECK-LABEL: sxt16n:
; CHECK: sxt @r12
%0 = bitcast i16* %x to i8*
%1 = load i8, i8* %0, align 1
%conv = sext i8 %1 to i16
store i16 %conv, i16* %x, align 2
ret void
}

0 comments on commit 7f3ec90

Please sign in to comment.