[PATCH] D22051: MergeSimilarFunctions: a code size pass to merge functions with small differences
Tobias Edler von Koch via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 7 15:54:47 PDT 2016
tobiasvk added a comment.
Thanks David for the quick review - agree with most of your points, some comments added.
================
Comment at: lib/Transforms/IPO/MergeSimilarFunctions.cpp:100
@@ +99,3 @@
+
+static const char *MERGED_SUFFIX = "__merged";
+
----------------
majnemer wrote:
> This is not a good suffix to use, it is not reserved (user code can have it).
>
> I'd suggest `.merged` because it will demangle nicely and is impossible to get to via most normal means.
Yes, I've been thinking that too. I do vaguely recall, though, that some architectures can't handle symbol names with dots in them? Anyone have any better recollection of this? It's certainly fine for Hexagon.
================
Comment at: lib/Transforms/IPO/MergeSimilarFunctions.cpp:618-645
@@ +617,30 @@
+ }
+ if (const CmpInst *CI = dyn_cast<CmpInst>(I1))
+ return CI->getPredicate() == cast<CmpInst>(I2)->getPredicate();
+ if (const CallInst *CI = dyn_cast<CallInst>(I1))
+ return CI->getCallingConv() == cast<CallInst>(I2)->getCallingConv() &&
+ CI->getAttributes() == cast<CallInst>(I2)->getAttributes();
+ if (const InvokeInst *CI = dyn_cast<InvokeInst>(I1))
+ return CI->getCallingConv() == cast<InvokeInst>(I2)->getCallingConv() &&
+ CI->getAttributes() == cast<InvokeInst>(I2)->getAttributes();
+ if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(I1))
+ return IVI->getIndices() == cast<InsertValueInst>(I2)->getIndices();
+ if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(I1))
+ return EVI->getIndices() == cast<ExtractValueInst>(I2)->getIndices();
+ if (const FenceInst *FI = dyn_cast<FenceInst>(I1))
+ return FI->getOrdering() == cast<FenceInst>(I2)->getOrdering() &&
+ FI->getSynchScope() == cast<FenceInst>(I2)->getSynchScope();
+ if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(I1)) {
+ const AtomicCmpXchgInst *CXI2 = cast<AtomicCmpXchgInst>(I2);
+ return CXI->isVolatile() == CXI2->isVolatile() &&
+ CXI->isWeak() == CXI2->isWeak() &&
+ CXI->getSuccessOrdering() == CXI2->getSuccessOrdering() &&
+ CXI->getFailureOrdering() == CXI2->getFailureOrdering() &&
+ CXI->getSynchScope() == CXI2->getSynchScope();
+ }
+ if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I1))
+ return RMWI->getOperation() == cast<AtomicRMWInst>(I2)->getOperation() &&
+ RMWI->isVolatile() == cast<AtomicRMWInst>(I2)->isVolatile() &&
+ RMWI->getOrdering() == cast<AtomicRMWInst>(I2)->getOrdering() &&
+ RMWI->getSynchScope() == cast<AtomicRMWInst>(I2)->getSynchScope();
+
----------------
majnemer wrote:
> This looks a lot like `haveSameSpecialState` in Instruction.cpp, it would be best to reuse that code.
Yep, except for some important differences:
- We treat pointer-to-A, pointer-to-B, and the corresponding int type as equivalent
- An alloca that allocates more space is 'equivalent' to one that allocates less.
MergeFunctions has its own copy of this stuff too.
================
Comment at: lib/Transforms/IPO/MergeSimilarFunctions.cpp:1375-1383
@@ +1374,11 @@
+
+// Replace G with an alias to F if possible, or else a thunk to F. Deletes G.
+void MergeSimilarFunctions::writeThunkOrAlias(Function *F, Function *G) {
+ if (isAliasCapable(G)) {
+ writeAlias(F, G);
+ return;
+ }
+
+ writeThunk(F, G);
+}
+
----------------
majnemer wrote:
> Why not let global-opt do this?
Merge(Similar)Functions typically runs near the end of the pipeline after GlobalOpt has already run.
http://reviews.llvm.org/D22051
More information about the llvm-commits
mailing list