[llvm-commits] [llvm] r169147 - in /llvm/trunk/include/llvm/ADT: PointerIntPair.h PointerUnion.h

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Dec 3 11:59:23 PST 2012


Author: akirtzidis
Date: Mon Dec  3 13:59:23 2012
New Revision: 169147

URL: http://llvm.org/viewvc/llvm-project?rev=169147&view=rev
Log:
Eliminate redundant bitwise operations when using a llvm/ADT/PointerUnion.

For comparison, with this code sample:

PointerUnion<int *, char *> Data;
PointerUnion<int *, char *> foo1() {
	Data = new int;
	return new int;
}
PointerUnion<int *, char *> foo2() {
	Data = new char;
	return new char;
}

Before this patch we would get:

define i64 @_Z4foo1v() uwtable ssp {
  %1 = tail call noalias i8* @_Znwm(i64 4)
  %2 = ptrtoint i8* %1 to i64
  %3 = load i64* getelementptr inbounds (%"class.llvm::PointerUnion"* @Data, i64 0, i32 0, i32 0), align 8
  %4 = and i64 %3, 1
  %.masked.i = and i64 %2, -3
  %5 = or i64 %4, %.masked.i
  store i64 %5, i64* getelementptr inbounds (%"class.llvm::PointerUnion"* @Data, i64 0, i32 0, i32 0), align 8
  %6 = tail call noalias i8* @_Znwm(i64 4)
  %7 = ptrtoint i8* %6 to i64
  %8 = and i64 %7, -3
  ret i64 %8
}

define i64 @_Z4foo2v() uwtable ssp {
  %1 = tail call noalias i8* @_Znwm(i64 1)
  %2 = ptrtoint i8* %1 to i64
  %3 = load i64* getelementptr inbounds (%"class.llvm::PointerUnion"* @Data, i64 0, i32 0, i32 0), align 8
  %4 = and i64 %3, 1
  %5 = or i64 %2, %4
  %6 = or i64 %5, 2
  store i64 %6, i64* getelementptr inbounds (%"class.llvm::PointerUnion"* @Data, i64 0, i32 0, i32 0), align 8
  %7 = tail call noalias i8* @_Znwm(i64 1)
  %8 = ptrtoint i8* %7 to i64
  %9 = or i64 %8, 2
  ret i64 %9
}

After the patch:

define i64 @_Z4foo1v() uwtable ssp {
  %1 = tail call noalias i8* @_Znwm(i64 4)
  %2 = ptrtoint i8* %1 to i64
  store i64 %2, i64* getelementptr inbounds (%"class.llvm::PointerUnion"* @Data, i64 0, i32 0, i32 0), align 8
  %3 = tail call noalias i8* @_Znwm(i64 4)
  %4 = ptrtoint i8* %3 to i64
  ret i64 %4
}

declare noalias i8* @_Znwm(i64)

define i64 @_Z4foo2v() uwtable ssp {
  %1 = tail call noalias i8* @_Znwm(i64 1)
  %2 = ptrtoint i8* %1 to i64
  %3 = or i64 %2, 2
  store i64 %3, i64* getelementptr inbounds (%"class.llvm::PointerUnion"* @Data, i64 0, i32 0, i32 0), align 8
  %4 = tail call noalias i8* @_Znwm(i64 1)
  %5 = ptrtoint i8* %4 to i64
  %6 = or i64 %5, 2
  ret i64 %6
}

Modified:
    llvm/trunk/include/llvm/ADT/PointerIntPair.h
    llvm/trunk/include/llvm/ADT/PointerUnion.h

Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=169147&r1=169146&r2=169147&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original)
+++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Mon Dec  3 13:59:23 2012
@@ -57,11 +57,13 @@
   };
 public:
   PointerIntPair() : Value(0) {}
-  PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
+  PointerIntPair(PointerTy Ptr, IntType Int) {
     assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
            "PointerIntPair formed with integer size too large for pointer");
-    setPointer(Ptr);
-    setInt(Int);
+    setPointerAndInt(Ptr, Int);
+  }
+  explicit PointerIntPair(PointerTy Ptr) {
+    initWithPointer(Ptr);
   }
 
   PointerTy getPointer() const {
@@ -91,6 +93,25 @@
     Value |= IntVal << IntShift;  // Set new integer.
   }
 
+  void initWithPointer(PointerTy Ptr) {
+    intptr_t PtrVal
+      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
+    assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+           "Pointer is not sufficiently aligned");
+    Value = PtrVal;
+  }
+
+  void setPointerAndInt(PointerTy Ptr, IntType Int) {
+    intptr_t PtrVal
+      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
+    assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+           "Pointer is not sufficiently aligned");
+    intptr_t IntVal = Int;
+    assert(IntVal < (1 << IntBits) && "Integer too large for field");
+
+    Value = PtrVal | (IntVal << IntShift);
+  }
+
   PointerTy const *getAddrOfPointer() const {
     return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
   }

Modified: llvm/trunk/include/llvm/ADT/PointerUnion.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerUnion.h?rev=169147&r1=169146&r2=169147&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/PointerUnion.h (original)
+++ llvm/trunk/include/llvm/ADT/PointerUnion.h Mon Dec  3 13:59:23 2012
@@ -95,15 +95,11 @@
   public:
     PointerUnion() {}
     
-    PointerUnion(PT1 V) {
-      Val.setPointer(
-         const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
-      Val.setInt(0);
-    }
-    PointerUnion(PT2 V) {
-      Val.setPointer(
-         const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
-      Val.setInt(1);
+    PointerUnion(PT1 V) : Val(
+      const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
+    }
+    PointerUnion(PT2 V) : Val(
+      const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
     }
     
     /// isNull - Return true if the pointer held in the union is null,
@@ -160,15 +156,14 @@
     /// Assignment operators - Allow assigning into this union from either
     /// pointer type, setting the discriminator to remember what it came from.
     const PointerUnion &operator=(const PT1 &RHS) {
-      Val.setPointer(
+      Val.initWithPointer(
          const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
-      Val.setInt(0);
       return *this;
     }
     const PointerUnion &operator=(const PT2 &RHS) {
-      Val.setPointer(
-        const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)));
-      Val.setInt(1);
+      Val.setPointerAndInt(
+        const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
+        1);
       return *this;
     }
     





More information about the llvm-commits mailing list