mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
6777be3446
Last commit put it in Constants.cpp instead of Operator.cpp git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237960 91177308-0d34-0410-b5e6-96231b3b80d8
45 lines
1.5 KiB
C++
45 lines
1.5 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();
|
|
}
|
|
|
|
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 = dyn_cast<StructType>(*GTI)) {
|
|
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;
|
|
}
|
|
}
|