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