[llvm-commits] CVS: llvm/lib/Target/ARM/ARMCommon.cpp ARMCommon.h ARMISelDAGToDAG.cpp ARMRegisterInfo.cpp
Lauro Ramos Venancio
lauro.venancio at gmail.com
Fri Jan 12 12:36:08 PST 2007
Changes in directory llvm/lib/Target/ARM:
ARMCommon.cpp added (r1.1)
ARMCommon.h added (r1.1)
ARMISelDAGToDAG.cpp updated: 1.97 -> 1.98
ARMRegisterInfo.cpp updated: 1.31 -> 1.32
---
Log message:
Build constants using instructions mov/orr or mvn/eor.
---
Diffs of the changes: (+186 -89)
ARMCommon.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++
ARMCommon.h | 22 ++++++++++++
ARMISelDAGToDAG.cpp | 94 ++++++++++++++++++++++++++++++++++++++++------------
ARMRegisterInfo.cpp | 75 +++--------------------------------------
4 files changed, 186 insertions(+), 89 deletions(-)
Index: llvm/lib/Target/ARM/ARMCommon.cpp
diff -c /dev/null llvm/lib/Target/ARM/ARMCommon.cpp:1.1
*** /dev/null Fri Jan 12 14:35:59 2007
--- llvm/lib/Target/ARM/ARMCommon.cpp Fri Jan 12 14:35:49 2007
***************
*** 0 ****
--- 1,84 ----
+ //===-- ARMCommon.cpp - Define support functions for ARM --------*- C++ -*-===//
+ //
+ // 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 "ARMCommon.h"
+
+ static inline unsigned rotateL(unsigned x, unsigned n){
+ return ((x << n) | (x >> (32 - n)));
+ }
+
+ static inline unsigned rotateR(unsigned x, unsigned n){
+ return ((x >> n) | (x << (32 - n)));
+ }
+
+ // finds the end position of largest sequence of zeros in binary representation
+ // of 'immediate'.
+ static int findLargestZeroSequence(unsigned immediate){
+ int max_zero_pos = 0;
+ int max_zero_length = 0;
+ int zero_pos;
+ int zero_length;
+ int pos = 0;
+ int end_pos;
+
+ while ((immediate & 0x3) == 0) {
+ immediate = rotateR(immediate, 2);
+ pos+=2;
+ }
+ end_pos = pos+32;
+
+ while (pos<end_pos){
+ while (((immediate & 0x3) != 0)&&(pos<end_pos)) {
+ immediate = rotateR(immediate, 2);
+ pos+=2;
+ }
+ zero_pos = pos;
+ while (((immediate & 0x3) == 0)&&(pos<end_pos)) {
+ immediate = rotateR(immediate, 2);
+ pos+=2;
+ }
+ zero_length = pos - zero_pos;
+ if (zero_length > max_zero_length){
+ max_zero_length = zero_length;
+ max_zero_pos = zero_pos % 32;
+ }
+
+ }
+
+ return (max_zero_pos + max_zero_length) % 32;
+ }
+
+ std::vector<unsigned> splitImmediate(unsigned immediate){
+ std::vector<unsigned> immediatePieces;
+
+ if (immediate == 0){
+ immediatePieces.push_back(0);
+ } else {
+ int start_pos = findLargestZeroSequence(immediate);
+ unsigned immediate_tmp = rotateR(immediate, start_pos);
+ int pos = 0;
+ while (pos < 32){
+ while(((immediate_tmp&0x3) == 0)&&(pos<32)){
+ immediate_tmp = rotateR(immediate_tmp,2);
+ pos+=2;
+ }
+ if (pos < 32){
+ immediatePieces.push_back(rotateL(immediate_tmp&0xFF,
+ (start_pos + pos) % 32 ));
+ immediate_tmp = rotateR(immediate_tmp,8);
+ pos+=8;
+ }
+ }
+ }
+ return immediatePieces;
+ }
Index: llvm/lib/Target/ARM/ARMCommon.h
diff -c /dev/null llvm/lib/Target/ARM/ARMCommon.h:1.1
*** /dev/null Fri Jan 12 14:36:08 2007
--- llvm/lib/Target/ARM/ARMCommon.h Fri Jan 12 14:35:49 2007
***************
*** 0 ****
--- 1,22 ----
+ //===-- ARMCommon.h - Define support functions for ARM ----------*- C++ -*-===//
+ //
+ // 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.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ //
+ //
+ //===----------------------------------------------------------------------===//
+
+ #ifndef ARM_COMMON_H
+ #define ARM_COMMON_H
+
+ #include <vector>
+
+ std::vector<unsigned> splitImmediate(unsigned immediate);
+
+ #endif
Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.97 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.98
--- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.97 Thu Jan 4 08:01:38 2007
+++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Fri Jan 12 14:35:49 2007
@@ -13,6 +13,7 @@
#include "ARM.h"
#include "ARMTargetMachine.h"
+#include "ARMCommon.h"
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
@@ -27,6 +28,7 @@
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
#include <vector>
using namespace llvm;
@@ -103,8 +105,8 @@
setOperationAction(ISD::VAEND, MVT::Other, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
- setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
- setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
+ setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
+ setOperationAction(ISD::ConstantFP, MVT::f32, Custom);
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
@@ -543,6 +545,70 @@
return CPI;
}
+SDOperand LegalizeImmediate(uint32_t immediate, SelectionDAG &DAG,
+ bool canReturnConstant){
+ SDOperand Shift = DAG.getTargetConstant(0, MVT::i32);
+ SDOperand ShiftType = DAG.getTargetConstant(ARMShift::LSL, MVT::i32);
+ std::vector<unsigned>immediatePieces = splitImmediate(immediate);
+ if (immediatePieces.size()>1){
+ unsigned movInst = ARM::MOV;
+ unsigned orInst = ARM::ORR;
+ SDNode *node;
+ //try mvn
+ std::vector<unsigned>immediateNegPieces = splitImmediate(~immediate);
+ if (immediatePieces.size() > immediateNegPieces.size()) {
+ //use mvn/eor
+ movInst = ARM::MVN;
+ orInst = ARM::EOR;
+ immediatePieces = immediateNegPieces;
+ }
+ SDOperand n = DAG.getTargetConstant(immediatePieces[0], MVT::i32);
+ node = DAG.getTargetNode(movInst, MVT::i32, n, Shift, ShiftType);
+ std::vector<unsigned>::iterator it;
+ for (it=immediatePieces.begin()+1; it != immediatePieces.end(); ++it){
+ n = DAG.getTargetConstant(*it, MVT::i32);
+ SDOperand ops[] = {SDOperand(node, 0), n, Shift, ShiftType};
+ node = DAG.getTargetNode(orInst, MVT::i32, ops, 4);
+ }
+ return SDOperand(node, 0);
+ } else {
+ if (canReturnConstant)
+ return DAG.getTargetConstant(immediate, MVT::i32);
+ else {
+ SDOperand n = DAG.getTargetConstant(immediate, MVT::i32);
+ SDNode *node = DAG.getTargetNode(ARM::MOV, MVT::i32, n, Shift,
+ ShiftType);
+ return SDOperand(node, 0);
+ }
+ }
+}
+
+static SDOperand LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
+ MVT::ValueType VT = Op.getValueType();
+ SDOperand Shift = DAG.getTargetConstant(0, MVT::i32);
+ SDOperand ShiftType = DAG.getTargetConstant(ARMShift::LSL, MVT::i32);
+ SDNode *node;
+ switch (VT) {
+ default: assert(0 && "VT!=f32 && VT!=f64");
+ case MVT::f32: {
+ float val = cast<ConstantFPSDNode>(Op)->getValue();
+ uint32_t i32_val = FloatToBits(val);
+ SDOperand c = LegalizeImmediate(i32_val, DAG, false);
+ node = DAG.getTargetNode(ARM::FMSR, MVT::f32, c);
+ break;
+ }
+ case MVT::f64: {
+ double val = cast<ConstantFPSDNode>(Op)->getValue();
+ uint64_t i64_val = DoubleToBits(val);
+ SDOperand hi = LegalizeImmediate(Hi_32(i64_val), DAG, false);
+ SDOperand lo = LegalizeImmediate(Lo_32(i64_val), DAG, false);
+ node = DAG.getTargetNode(ARM::FMDRR, MVT::f64, lo, hi);
+ break;
+ }
+ }
+ return SDOperand(node, 0);
+}
+
static SDOperand LowerGlobalAddress(SDOperand Op,
SelectionDAG &DAG) {
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
@@ -849,6 +915,8 @@
abort();
case ISD::ConstantPool:
return LowerConstantPool(Op, DAG);
+ case ISD::ConstantFP:
+ return LowerConstantFP(Op, DAG);
case ISD::GlobalAddress:
return LowerGlobalAddress(Op, DAG);
case ISD::FP_TO_SINT:
@@ -942,26 +1010,12 @@
switch(N.getOpcode()) {
case ISD::Constant: {
uint32_t val = cast<ConstantSDNode>(N)->getValue();
- if(!isRotInt8Immediate(val)) {
- SDOperand Z = CurDAG->getTargetConstant(0, MVT::i32);
- SDNode *n;
- if (isRotInt8Immediate(~val)) {
- SDOperand C = CurDAG->getTargetConstant(~val, MVT::i32);
- n = CurDAG->getTargetNode(ARM::MVN, MVT::i32, C, Z, Z);
- } else {
- Constant *C = ConstantInt::get(Type::Int32Ty, val);
- int alignment = 2;
- SDOperand Addr = CurDAG->getTargetConstantPool(C, MVT::i32, alignment);
- n = CurDAG->getTargetNode(ARM::LDR, MVT::i32, Addr, Z);
- }
- Arg = SDOperand(n, 0);
- } else
- Arg = CurDAG->getTargetConstant(val, MVT::i32);
-
- Shift = CurDAG->getTargetConstant(0, MVT::i32);
- ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
+ Shift = CurDAG->getTargetConstant(0, MVT::i32);
+ ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
+ Arg = LegalizeImmediate(val, *CurDAG, true);
return true;
}
+
case ISD::SRA:
Arg = N.getOperand(0);
Shift = N.getOperand(1);
Index: llvm/lib/Target/ARM/ARMRegisterInfo.cpp
diff -u llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.31 llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.32
--- llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.31 Tue Jan 2 15:31:55 2007
+++ llvm/lib/Target/ARM/ARMRegisterInfo.cpp Fri Jan 12 14:35:49 2007
@@ -14,6 +14,7 @@
#include "ARM.h"
#include "ARMRegisterInfo.h"
+#include "ARMCommon.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -35,82 +36,18 @@
return NoFramePointerElim || MFI->hasVarSizedObjects();
}
-static inline unsigned rotateL(unsigned x, unsigned n){
- return ((x << n) | (x >> (32 - n)));
-}
-
-static inline unsigned rotateR(unsigned x, unsigned n){
- return ((x >> n) | (x << (32 - n)));
-}
-
-// finds the end position of largest sequence of zeros in binary representation
-// of 'immediate'.
-static int findLargestZeroSequence(unsigned immediate){
- int max_zero_pos;
- int max_zero_length = 0;
- int zero_pos;
- int zero_length;
- int pos = 0;
- int end_pos;
-
- while ((immediate & 0x3) == 0) {
- immediate = rotateR(immediate, 2);
- pos+=2;
- }
- end_pos = pos+32;
-
- while (pos<end_pos){
- while ((immediate & 0x3) != 0) {
- immediate = rotateR(immediate, 2);
- pos+=2;
- }
- zero_pos = pos;
- while ((immediate & 0x3) == 0) {
- immediate = rotateR(immediate, 2);
- pos+=2;
- }
- zero_length = pos - zero_pos;
- if (zero_length > max_zero_length){
- max_zero_length = zero_length;
- max_zero_pos = zero_pos % 32;
- }
-
- }
-
- return (max_zero_pos + max_zero_length) % 32;
-}
-
static void splitInstructionWithImmediate(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
const TargetInstrDescriptor &TID,
unsigned DestReg,
unsigned OrigReg,
unsigned immediate){
-
- if (immediate == 0){
- BuildMI(BB, I, TID, DestReg).addReg(OrigReg).addImm(0)
- .addImm(0).addImm(ARMShift::LSL);
- return;
- }
-
- int start_pos = findLargestZeroSequence(immediate);
- unsigned immediate_tmp = rotateR(immediate, start_pos);
-
- int pos = 0;
- while (pos < 32){
- while(((immediate_tmp&0x3) == 0)&&(pos<32)){
- immediate_tmp = rotateR(immediate_tmp,2);
- pos+=2;
- }
- if (pos < 32){
- BuildMI(BB, I, TID, DestReg).addReg(OrigReg)
- .addImm(rotateL(immediate_tmp&0xFF, (start_pos + pos) % 32 ))
- .addImm(0).addImm(ARMShift::LSL);
- immediate_tmp = rotateR(immediate_tmp,8);
- pos+=8;
- }
+ std::vector<unsigned> immediatePieces = splitImmediate(immediate);
+ std::vector<unsigned>::iterator it;
+ for (it=immediatePieces.begin(); it != immediatePieces.end(); ++it){
+ BuildMI(BB, I, TID, DestReg).addReg(OrigReg)
+ .addImm(*it).addImm(0).addImm(ARMShift::LSL);
}
-
}
ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii)
More information about the llvm-commits
mailing list