[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