mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-22 23:24:59 +00:00
DataLayout is mandatory, update the API to reflect it with references.
Summary: Now that the DataLayout is a mandatory part of the module, let's start cleaning the codebase. This patch is a first attempt at doing that. This patch is not exactly NFC as for instance some places were passing a nullptr instead of the DataLayout, possibly just because there was a default value on the DataLayout argument to many functions in the API. Even though it is not purely NFC, there is no change in the validation. I turned as many pointer to DataLayout to references, this helped figuring out all the places where a nullptr could come up. I had initially a local version of this patch broken into over 30 independant, commits but some later commit were cleaning the API and touching part of the code modified in the previous commits, so it seemed cleaner without the intermediate state. Test Plan: Reviewers: echristo Subscribers: llvm-commits From: Mehdi Amini <mehdi.amini@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231740 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -69,16 +69,15 @@ namespace {
|
||||
bool runOnSCC(CallGraphSCC &SCC) override;
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
explicit ArgPromotion(unsigned maxElements = 3)
|
||||
: CallGraphSCCPass(ID), DL(nullptr), maxElements(maxElements) {
|
||||
: CallGraphSCCPass(ID), maxElements(maxElements) {
|
||||
initializeArgPromotionPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
/// A vector used to hold the indices of a single GEP instruction
|
||||
typedef std::vector<uint64_t> IndicesVector;
|
||||
|
||||
const DataLayout *DL;
|
||||
private:
|
||||
bool isDenselyPacked(Type *type);
|
||||
bool isDenselyPacked(Type *type, const DataLayout &DL);
|
||||
bool canPaddingBeAccessed(Argument *Arg);
|
||||
CallGraphNode *PromoteArguments(CallGraphNode *CGN);
|
||||
bool isSafeToPromoteArgument(Argument *Arg, bool isByVal) const;
|
||||
@@ -125,7 +124,7 @@ bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) {
|
||||
}
|
||||
|
||||
/// \brief Checks if a type could have padding bytes.
|
||||
bool ArgPromotion::isDenselyPacked(Type *type) {
|
||||
bool ArgPromotion::isDenselyPacked(Type *type, const DataLayout &DL) {
|
||||
|
||||
// There is no size information, so be conservative.
|
||||
if (!type->isSized())
|
||||
@@ -133,7 +132,7 @@ bool ArgPromotion::isDenselyPacked(Type *type) {
|
||||
|
||||
// If the alloc size is not equal to the storage size, then there are padding
|
||||
// bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
|
||||
if (!DL || DL->getTypeSizeInBits(type) != DL->getTypeAllocSizeInBits(type))
|
||||
if (DL.getTypeSizeInBits(type) != DL.getTypeAllocSizeInBits(type))
|
||||
return false;
|
||||
|
||||
if (!isa<CompositeType>(type))
|
||||
@@ -141,19 +140,20 @@ bool ArgPromotion::isDenselyPacked(Type *type) {
|
||||
|
||||
// For homogenous sequential types, check for padding within members.
|
||||
if (SequentialType *seqTy = dyn_cast<SequentialType>(type))
|
||||
return isa<PointerType>(seqTy) || isDenselyPacked(seqTy->getElementType());
|
||||
return isa<PointerType>(seqTy) ||
|
||||
isDenselyPacked(seqTy->getElementType(), DL);
|
||||
|
||||
// Check for padding within and between elements of a struct.
|
||||
StructType *StructTy = cast<StructType>(type);
|
||||
const StructLayout *Layout = DL->getStructLayout(StructTy);
|
||||
const StructLayout *Layout = DL.getStructLayout(StructTy);
|
||||
uint64_t StartPos = 0;
|
||||
for (unsigned i = 0, E = StructTy->getNumElements(); i < E; ++i) {
|
||||
Type *ElTy = StructTy->getElementType(i);
|
||||
if (!isDenselyPacked(ElTy))
|
||||
if (!isDenselyPacked(ElTy, DL))
|
||||
return false;
|
||||
if (StartPos != Layout->getElementOffsetInBits(i))
|
||||
return false;
|
||||
StartPos += DL->getTypeAllocSizeInBits(ElTy);
|
||||
StartPos += DL.getTypeAllocSizeInBits(ElTy);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -207,8 +207,6 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
|
||||
// Make sure that it is local to this module.
|
||||
if (!F || !F->hasLocalLinkage()) return nullptr;
|
||||
|
||||
DL = &F->getParent()->getDataLayout();
|
||||
|
||||
// First check: see if there are any pointer arguments! If not, quick exit.
|
||||
SmallVector<Argument*, 16> PointerArgs;
|
||||
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
|
||||
@@ -235,6 +233,7 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
|
||||
// IR, while in the callee the classification is determined dynamically based
|
||||
// on the number of registers consumed so far.
|
||||
if (F->isVarArg()) return nullptr;
|
||||
const DataLayout &DL = F->getParent()->getDataLayout();
|
||||
|
||||
// Check to see which arguments are promotable. If an argument is promotable,
|
||||
// add it to ArgsToPromote.
|
||||
@@ -249,8 +248,8 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
|
||||
// packed or if we can prove the padding bytes are never accessed. This does
|
||||
// not apply to inalloca.
|
||||
bool isSafeToPromote =
|
||||
PtrArg->hasByValAttr() &&
|
||||
(isDenselyPacked(AgTy) || !canPaddingBeAccessed(PtrArg));
|
||||
PtrArg->hasByValAttr() &&
|
||||
(isDenselyPacked(AgTy, DL) || !canPaddingBeAccessed(PtrArg));
|
||||
if (isSafeToPromote) {
|
||||
if (StructType *STy = dyn_cast<StructType>(AgTy)) {
|
||||
if (maxElements > 0 && STy->getNumElements() > maxElements) {
|
||||
@@ -309,9 +308,9 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
|
||||
|
||||
/// AllCallersPassInValidPointerForArgument - Return true if we can prove that
|
||||
/// all callees pass in a valid pointer for the specified function argument.
|
||||
static bool AllCallersPassInValidPointerForArgument(Argument *Arg,
|
||||
const DataLayout *DL) {
|
||||
static bool AllCallersPassInValidPointerForArgument(Argument *Arg) {
|
||||
Function *Callee = Arg->getParent();
|
||||
const DataLayout &DL = Callee->getParent()->getDataLayout();
|
||||
|
||||
unsigned ArgNo = Arg->getArgNo();
|
||||
|
||||
@@ -429,7 +428,7 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg,
|
||||
GEPIndicesSet ToPromote;
|
||||
|
||||
// If the pointer is always valid, any load with first index 0 is valid.
|
||||
if (isByValOrInAlloca || AllCallersPassInValidPointerForArgument(Arg, DL))
|
||||
if (isByValOrInAlloca || AllCallersPassInValidPointerForArgument(Arg))
|
||||
SafeToUnconditionallyLoad.insert(IndicesVector(1, 0));
|
||||
|
||||
// First, iterate the entry block and mark loads of (geps of) arguments as
|
||||
|
Reference in New Issue
Block a user