Thanks!<span></span><br><br>On Tuesday, September 23, 2014, Reid Kleckner <<a href="mailto:reid@kleckner.net">reid@kleckner.net</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Tue Sep 23 17:33:01 2014<br>
New Revision: 218337<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=218337&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=218337&view=rev</a><br>
Log:<br>
GlobalOpt: Preserve comdats of unoptimized initializers<br>
<br>
Rather than slurping in and splatting out the whole ctor list, preserve<br>
the existing array entries without trying to understand them. Only<br>
remove the entries that we know we can optimize away. This way we don't<br>
need to wire through priority and comdats or anything else we might add.<br>
<br>
Fixes a linker issue where the .init_array or .ctors entry would point<br>
to discarded initialization code if the comdat group from the TU with<br>
the faulty global_ctors entry was dropped.<br>
<br>
Added:<br>
llvm/trunk/test/Transforms/GlobalOpt/preserve-comdats.ll<br>
Modified:<br>
llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp<br>
<br>
Modified: llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp?rev=218337&r1=218336&r2=218337&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp?rev=218337&r1=218336&r2=218337&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Utils/CtorUtils.cpp Tue Sep 23 17:33:01 2014<br>
@@ -11,6 +11,7 @@<br>
//<br>
//===----------------------------------------------------------------------===//<br>
<br>
+#include "llvm/ADT/BitVector.h"<br>
#include "llvm/Transforms/Utils/CtorUtils.h"<br>
#include "llvm/IR/Constants.h"<br>
#include "llvm/IR/Function.h"<br>
@@ -24,41 +25,22 @@<br>
namespace llvm {<br>
<br>
namespace {<br>
-/// Given a specified llvm.global_ctors list, install the<br>
-/// specified array.<br>
-void installGlobalCtors(GlobalVariable *GCL,<br>
- const std::vector<Function *> &Ctors) {<br>
- // If we made a change, reassemble the initializer list.<br>
- Constant *CSVals[3];<br>
-<br>
- StructType *StructTy =<br>
- cast<StructType>(GCL->getType()->getElementType()->getArrayElementType());<br>
-<br>
- // Create the new init list.<br>
- std::vector<Constant *> CAList;<br>
- for (Function *F : Ctors) {<br>
- Type *Int32Ty = Type::getInt32Ty(GCL->getContext());<br>
- if (F) {<br>
- CSVals[0] = ConstantInt::get(Int32Ty, 65535);<br>
- CSVals[1] = F;<br>
- } else {<br>
- CSVals[0] = ConstantInt::get(Int32Ty, 0x7fffffff);<br>
- CSVals[1] = Constant::getNullValue(StructTy->getElementType(1));<br>
- }<br>
- // FIXME: Only allow the 3-field form in LLVM 4.0.<br>
- size_t NumElts = StructTy->getNumElements();<br>
- if (NumElts > 2)<br>
- CSVals[2] = Constant::getNullValue(StructTy->getElementType(2));<br>
- CAList.push_back(<br>
- ConstantStruct::get(StructTy, makeArrayRef(CSVals, NumElts)));<br>
- }<br>
-<br>
- // Create the array initializer.<br>
- Constant *CA =<br>
- ConstantArray::get(ArrayType::get(StructTy, CAList.size()), CAList);<br>
+/// Given a specified llvm.global_ctors list, remove the listed elements.<br>
+void removeGlobalCtors(GlobalVariable *GCL, const BitVector &CtorsToRemove) {<br>
+ // Filter out the initializer elements to remove.<br>
+ ConstantArray *OldCA = cast<ConstantArray>(GCL->getInitializer());<br>
+ SmallVector<Constant *, 10> CAList;<br>
+ for (unsigned I = 0, E = OldCA->getNumOperands(); I < E; ++I)<br>
+ if (!CtorsToRemove.test(I))<br>
+ CAList.push_back(OldCA->getOperand(I));<br>
+<br>
+ // Create the new array initializer.<br>
+ ArrayType *ATy =<br>
+ ArrayType::get(OldCA->getType()->getElementType(), CAList.size());<br>
+ Constant *CA = ConstantArray::get(ATy, CAList);<br>
<br>
// If we didn't change the number of elements, don't create a new GV.<br>
- if (CA->getType() == GCL->getInitializer()->getType()) {<br>
+ if (CA->getType() == OldCA->getType()) {<br>
GCL->setInitializer(CA);<br>
return;<br>
}<br>
@@ -82,7 +64,7 @@ void installGlobalCtors(GlobalVariable *<br>
<br>
/// Given a llvm.global_ctors list that we can understand,<br>
/// return a list of the functions and null terminator as a vector.<br>
-std::vector<Function*> parseGlobalCtors(GlobalVariable *GV) {<br>
+std::vector<Function *> parseGlobalCtors(GlobalVariable *GV) {<br>
if (GV->getInitializer()->isNullValue())<br>
return std::vector<Function *>();<br>
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());<br>
@@ -147,17 +129,15 @@ bool optimizeGlobalCtorsList(Module &M,<br>
bool MadeChange = false;<br>
<br>
// Loop over global ctors, optimizing them when we can.<br>
- for (unsigned i = 0; i != Ctors.size(); ++i) {<br>
+ unsigned NumCtors = Ctors.size();<br>
+ BitVector CtorsToRemove(NumCtors);<br>
+ for (unsigned i = 0; i != Ctors.size() && NumCtors > 0; ++i) {<br>
Function *F = Ctors[i];<br>
// Found a null terminator in the middle of the list, prune off the rest of<br>
// the list.<br>
- if (!F) {<br>
- if (i != Ctors.size() - 1) {<br>
- Ctors.resize(i + 1);<br>
- MadeChange = true;<br>
- }<br>
- break;<br>
- }<br>
+ if (!F)<br>
+ continue;<br>
+<br>
DEBUG(dbgs() << "Optimizing Global Constructor: " << *F << "\n");<br>
<br>
// We cannot simplify external ctor functions.<br>
@@ -166,9 +146,10 @@ bool optimizeGlobalCtorsList(Module &M,<br>
<br>
// If we can evaluate the ctor at compile time, do.<br>
if (ShouldRemove(F)) {<br>
- Ctors.erase(Ctors.begin() + i);<br>
+ Ctors[i] = nullptr;<br>
+ CtorsToRemove.set(i);<br>
+ NumCtors--;<br>
MadeChange = true;<br>
- --i;<br>
continue;<br>
}<br>
}<br>
@@ -176,7 +157,7 @@ bool optimizeGlobalCtorsList(Module &M,<br>
if (!MadeChange)<br>
return false;<br>
<br>
- installGlobalCtors(GlobalCtors, Ctors);<br>
+ removeGlobalCtors(GlobalCtors, CtorsToRemove);<br>
return true;<br>
}<br>
<br>
<br>
Added: llvm/trunk/test/Transforms/GlobalOpt/preserve-comdats.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/preserve-comdats.ll?rev=218337&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/preserve-comdats.ll?rev=218337&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/GlobalOpt/preserve-comdats.ll (added)<br>
+++ llvm/trunk/test/Transforms/GlobalOpt/preserve-comdats.ll Tue Sep 23 17:33:01 2014<br>
@@ -0,0 +1,37 @@<br>
+; RUN: opt -globalopt -S < %s | FileCheck %s<br>
+<br>
+$comdat_global = comdat any<br>
+<br>
+@comdat_global = weak_odr global i8 0, comdat $comdat_global<br>
+@simple_global = internal global i8 0<br>
+; CHECK: @comdat_global = weak_odr global i8 0, comdat $comdat_global<br>
+; CHECK: @simple_global = internal global i8 42<br>
+<br>
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [<br>
+ { i32, void ()*, i8* } { i32 65535, void ()* @init_comdat_global, i8* @comdat_global },<br>
+ { i32, void ()*, i8* } { i32 65535, void ()* @init_simple_global, i8* null }<br>
+]<br>
+; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]<br>
+; CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @init_comdat_global, i8* @comdat_global }]<br>
+<br>
+define void @init_comdat_global() {<br>
+ store i8 42, i8* @comdat_global<br>
+ ret void<br>
+}<br>
+; CHECK: define void @init_comdat_global()<br>
+<br>
+define internal void @init_simple_global() comdat $comdat_global {<br>
+ store i8 42, i8* @simple_global<br>
+ ret void<br>
+}<br>
+; CHECK-NOT: @init_simple_global()<br>
+<br>
+define i8* @use_simple() {<br>
+ ret i8* @simple_global<br>
+}<br>
+; CHECK: define i8* @use_simple()<br>
+<br>
+define i8* @use_comdat() {<br>
+ ret i8* @comdat_global<br>
+}<br>
+; CHECK: define i8* @use_comdat()<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="javascript:;" onclick="_e(event, 'cvml', 'llvm-commits@cs.uiuc.edu')">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote>