forked from OSchip/llvm-project
Allow argpromote to promote struct arguments with a specified number
of elements. Patch by Matthijs Kooijman! llvm-svn: 49962
This commit is contained in:
parent
575f24ef73
commit
eb6bb803a7
|
@ -123,9 +123,10 @@ ModulePass *createDeadArgHackingPass();
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// createArgumentPromotionPass - This pass promotes "by reference" arguments to
|
/// createArgumentPromotionPass - This pass promotes "by reference" arguments to
|
||||||
/// be passed by value.
|
/// be passed by value if the number of elements passed is smaller or
|
||||||
|
/// equal to maxElements (maxElements == 0 means always promote).
|
||||||
///
|
///
|
||||||
Pass *createArgumentPromotionPass();
|
Pass *createArgumentPromotionPass(unsigned maxElements = 3);
|
||||||
Pass *createStructRetPromotionPass();
|
Pass *createStructRetPromotionPass();
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
//
|
//
|
||||||
// This pass also handles aggregate arguments that are passed into a function,
|
// This pass also handles aggregate arguments that are passed into a function,
|
||||||
// scalarizing them if the elements of the aggregate are only loaded. Note that
|
// scalarizing them if the elements of the aggregate are only loaded. Note that
|
||||||
// it refuses to scalarize aggregates which would require passing in more than
|
// by default it refuses to scalarize aggregates which would require passing in more than
|
||||||
// three operands to the function, because passing thousands of operands for a
|
// three operands to the function, because passing thousands of operands for a
|
||||||
// large array or structure is unprofitable!
|
// large array or structure is unprofitable! This limit is can be configured or
|
||||||
|
// disabled, however.
|
||||||
//
|
//
|
||||||
// Note that this transformation could also be done for arguments that are only
|
// Note that this transformation could also be done for arguments that are only
|
||||||
// stored to (returning the value instead), but does not currently. This case
|
// stored to (returning the value instead), but does not currently. This case
|
||||||
|
@ -65,7 +66,7 @@ namespace {
|
||||||
|
|
||||||
virtual bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
|
virtual bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
|
||||||
static char ID; // Pass identification, replacement for typeid
|
static char ID; // Pass identification, replacement for typeid
|
||||||
ArgPromotion() : CallGraphSCCPass((intptr_t)&ID) {}
|
ArgPromotion(unsigned maxElements = 3) : CallGraphSCCPass((intptr_t)&ID), maxElements(maxElements) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool PromoteArguments(CallGraphNode *CGN);
|
bool PromoteArguments(CallGraphNode *CGN);
|
||||||
|
@ -73,6 +74,8 @@ namespace {
|
||||||
Function *DoPromotion(Function *F,
|
Function *DoPromotion(Function *F,
|
||||||
SmallPtrSet<Argument*, 8> &ArgsToPromote,
|
SmallPtrSet<Argument*, 8> &ArgsToPromote,
|
||||||
SmallPtrSet<Argument*, 8> &ByValArgsToTransform);
|
SmallPtrSet<Argument*, 8> &ByValArgsToTransform);
|
||||||
|
/// The maximum number of elements to expand, or 0 for unlimited.
|
||||||
|
unsigned maxElements;
|
||||||
};
|
};
|
||||||
|
|
||||||
char ArgPromotion::ID = 0;
|
char ArgPromotion::ID = 0;
|
||||||
|
@ -80,8 +83,8 @@ namespace {
|
||||||
"Promote 'by reference' arguments to scalars");
|
"Promote 'by reference' arguments to scalars");
|
||||||
}
|
}
|
||||||
|
|
||||||
Pass *llvm::createArgumentPromotionPass() {
|
Pass *llvm::createArgumentPromotionPass(unsigned maxElements) {
|
||||||
return new ArgPromotion();
|
return new ArgPromotion(maxElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArgPromotion::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
|
bool ArgPromotion::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
|
||||||
|
@ -145,7 +148,11 @@ bool ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
|
||||||
if (isByVal) {
|
if (isByVal) {
|
||||||
const Type *AgTy = cast<PointerType>(PtrArg->getType())->getElementType();
|
const Type *AgTy = cast<PointerType>(PtrArg->getType())->getElementType();
|
||||||
if (const StructType *STy = dyn_cast<StructType>(AgTy))
|
if (const StructType *STy = dyn_cast<StructType>(AgTy))
|
||||||
if (STy->getNumElements() <= 3) {
|
if (maxElements > 0 && STy->getNumElements() > maxElements) {
|
||||||
|
DOUT << "argpromotion disable promoting argument '"
|
||||||
|
<< PtrArg->getName() << "' because it would require adding more "
|
||||||
|
<< "than " << maxElements << " arguments to the function.\n";
|
||||||
|
} else {
|
||||||
// If all the elements are first class types, we can promote it.
|
// If all the elements are first class types, we can promote it.
|
||||||
bool AllSimple = true;
|
bool AllSimple = true;
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
||||||
|
@ -278,12 +285,12 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const {
|
||||||
// to do.
|
// to do.
|
||||||
if (std::find(GEPIndices.begin(), GEPIndices.end(), Operands) ==
|
if (std::find(GEPIndices.begin(), GEPIndices.end(), Operands) ==
|
||||||
GEPIndices.end()) {
|
GEPIndices.end()) {
|
||||||
if (GEPIndices.size() == 3) {
|
if (maxElements > 0 && GEPIndices.size() == maxElements) {
|
||||||
DOUT << "argpromotion disable promoting argument '"
|
DOUT << "argpromotion disable promoting argument '"
|
||||||
<< Arg->getName() << "' because it would require adding more "
|
<< Arg->getName() << "' because it would require adding more "
|
||||||
<< "than 3 arguments to the function.\n";
|
<< "than " << maxElements << " arguments to the function.\n";
|
||||||
// We limit aggregate promotion to only promoting up to three elements
|
// We limit aggregate promotion to only promoting up to a fixed number
|
||||||
// of the aggregate.
|
// of elements of the aggregate.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
GEPIndices.push_back(Operands);
|
GEPIndices.push_back(Operands);
|
||||||
|
|
Loading…
Reference in New Issue