mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-11 21:57:55 +00:00
06115803f9
Instead, expose whether the current type is an array or a struct, if an array what the upper bound is, and if a struct the struct type itself. This is in preparation for a later change which will make PointerType derive from Type rather than SequentialType. Differential Revision: https://reviews.llvm.org/D26594 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288458 91177308-0d34-0410-b5e6-96231b3b80d8
51 lines
1.7 KiB
C++
51 lines
1.7 KiB
C++
#include "llvm/IR/Operator.h"
|
|
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/Type.h"
|
|
|
|
#include "ConstantsContext.h"
|
|
|
|
namespace llvm {
|
|
Type *GEPOperator::getSourceElementType() const {
|
|
if (auto *I = dyn_cast<GetElementPtrInst>(this))
|
|
return I->getSourceElementType();
|
|
return cast<GetElementPtrConstantExpr>(this)->getSourceElementType();
|
|
}
|
|
|
|
Type *GEPOperator::getResultElementType() const {
|
|
if (auto *I = dyn_cast<GetElementPtrInst>(this))
|
|
return I->getResultElementType();
|
|
return cast<GetElementPtrConstantExpr>(this)->getResultElementType();
|
|
}
|
|
|
|
bool GEPOperator::accumulateConstantOffset(const DataLayout &DL,
|
|
APInt &Offset) const {
|
|
assert(Offset.getBitWidth() ==
|
|
DL.getPointerSizeInBits(getPointerAddressSpace()) &&
|
|
"The offset must have exactly as many bits as our pointer.");
|
|
|
|
for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
|
|
GTI != GTE; ++GTI) {
|
|
ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
|
|
if (!OpC)
|
|
return false;
|
|
if (OpC->isZero())
|
|
continue;
|
|
|
|
// Handle a struct index, which adds its field offset to the pointer.
|
|
if (StructType *STy = GTI.getStructTypeOrNull()) {
|
|
unsigned ElementIdx = OpC->getZExtValue();
|
|
const StructLayout *SL = DL.getStructLayout(STy);
|
|
Offset += APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx));
|
|
continue;
|
|
}
|
|
|
|
// For array or vector indices, scale the index by the size of the type.
|
|
APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth());
|
|
Offset += Index * APInt(Offset.getBitWidth(),
|
|
DL.getTypeAllocSize(GTI.getIndexedType()));
|
|
}
|
|
return true;
|
|
}
|
|
}
|