diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-12-03 19:59:23 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-12-03 19:59:23 +0000 |
commit | acb8d9fbe3853394a2537985349993580309b8cd (patch) | |
tree | 40d035674f4501433fdbb6f0b2e5654fbad6796a /include/llvm/ADT | |
parent | ba917da3d38a9fc16d73e7ea341194b151ad1de0 (diff) | |
download | external_llvm-acb8d9fbe3853394a2537985349993580309b8cd.zip external_llvm-acb8d9fbe3853394a2537985349993580309b8cd.tar.gz external_llvm-acb8d9fbe3853394a2537985349993580309b8cd.tar.bz2 |
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
}
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169147 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r-- | include/llvm/ADT/PointerIntPair.h | 27 | ||||
-rw-r--r-- | include/llvm/ADT/PointerUnion.h | 21 |
2 files changed, 32 insertions, 16 deletions
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 71c379b..cce2efb 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -57,11 +57,13 @@ class PointerIntPair { }; 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 @@ public: 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(); } diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index a9e86d2..f42515a 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -95,15 +95,11 @@ namespace llvm { public: PointerUnion() {} - PointerUnion(PT1 V) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))); - Val.setInt(0); + PointerUnion(PT1 V) : Val( + const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) { } - PointerUnion(PT2 V) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V))); - Val.setInt(1); + 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 @@ namespace llvm { /// 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; } |