mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 17:31:50 +00:00
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
This commit is contained in:
parent
ba917da3d3
commit
acb8d9fbe3
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user