[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