[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c

Chris Lattner lattner at cs.uiuc.edu
Sun Jan 2 13:08:49 PST 2005



Changes in directory llvm-gcc/gcc:

llvm-expand.c updated: 1.74 -> 1.75
---
Log message:

Implement the majority of PR494: http://llvm.cs.uiuc.edu/PR494 .  For pointer subtractions of objects that
are a power of two, we emit a signed SHR instead of a signed divide.  This
gives us the performance we want in the common case.  Anything more will 
require extensions to the LLVM IR.


---
Diffs of the changes:  (+25 -0)

Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.74 llvm-gcc/gcc/llvm-expand.c:1.75
--- llvm-gcc/gcc/llvm-expand.c:1.74	Wed Dec  1 01:17:10 2004
+++ llvm-gcc/gcc/llvm-expand.c	Sun Jan  2 15:08:34 2005
@@ -6314,6 +6314,31 @@
     case UNORDERED_EXPR:
       break;
 
+    case EXACT_DIV_EXPR:
+      /* If this is a signed EXACT_DIV_EXPR by a constant, and we know that
+       * the RHS is a multiple of two, we strength reduce the result to use
+       * a signed SHR here.  We have no way in LLVM to represent EXACT_DIV_EXPR
+       * precisely, so this transform can't currently be performed at the LLVM
+       * level.
+       */
+      if (llvm_type_is_signed(op0->Ty) && op1->VTy == Constant) {
+        llvm_constant *C = V2C(op1);
+        if (C->Repr[0] > '0' && C->Repr[0] <= '9') {
+          unsigned Divisor = llvm_constant_get_integer_val(C);
+          
+          /* If the divisor is a power of two, we can do the xform. */
+          if (Divisor && (Divisor & (Divisor-1)) == 0) {
+            Opcode = O_Shr;  /* Perform a signed SHR */
+
+            unsigned ShAmt = 0;
+            for  (; Divisor > 1; Divisor >>= 1)
+              ++ShAmt;
+            op1 = llvm_constant_new_integral(UByteTy, ShAmt);
+          }
+        }
+      }
+      break;
+
     default:
       if (Opcode < O_SetEQ && (op0->Ty->ID == PointerTyID || 
                                op1->Ty->ID == PointerTyID)) {






More information about the llvm-commits mailing list