Commit 7dbba337 authored by Johannes Doerfert's avatar Johannes Doerfert
Browse files

[GlobalOpt][FIX] Do not embed initializers into AS!=0 globals

Not all address spaces support initializers for globals and we can
therefore not set them without checking if they are allowed. This
patch adds a hook into TTI to check if an AS allows non-undef
initializers. We disable it for all but address space 0 by default,
NVPTX and AMDGPU targets allow all but address space 3.

Reviewed By: tra

Differential Revision: https://reviews.llvm.org/D109337
parent ca134c39
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -383,6 +383,10 @@ public:

  bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const;

  /// Return true if globals in this address space can have initializers other
  /// than `undef`.
  bool canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const;

  unsigned getAssumedAddrSpace(const Value *V) const;

  /// Rewrite intrinsic call \p II such that \p OldV will be replaced with \p
@@ -1457,6 +1461,8 @@ public:
  virtual bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
                                          Intrinsic::ID IID) const = 0;
  virtual bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const = 0;
  virtual bool
  canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const = 0;
  virtual unsigned getAssumedAddrSpace(const Value *V) const = 0;
  virtual Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II,
                                                  Value *OldV,
@@ -1782,6 +1788,11 @@ public:
    return Impl.isNoopAddrSpaceCast(FromAS, ToAS);
  }

  bool
  canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const override {
    return Impl.canHaveNonUndefGlobalInitializerInAddressSpace(AS);
  }

  unsigned getAssumedAddrSpace(const Value *V) const override {
    return Impl.getAssumedAddrSpace(V);
  }
+3 −0
Original line number Diff line number Diff line
@@ -105,6 +105,9 @@ public:
  }

  bool isNoopAddrSpaceCast(unsigned, unsigned) const { return false; }
  bool canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const {
    return AS == 0;
  };

  unsigned getAssumedAddrSpace(const Value *V) const { return -1; }

+12 −3
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H

#include "llvm/IR/Instructions.h"
#include "llvm/Support/AtomicOrdering.h"

namespace llvm {
@@ -45,7 +46,7 @@ struct GlobalStatus {

    /// This global is stored to, but only its initializer and one other value
    /// is ever stored to it.  If this global isStoredOnce, we track the value
    /// stored to it in StoredOnceValue below.  This is only tracked for scalar
    /// stored to it via StoredOnceStore below.  This is only tracked for scalar
    /// globals.
    StoredOnce,

@@ -55,8 +56,16 @@ struct GlobalStatus {
  } StoredType = NotStored;

  /// If only one value (besides the initializer constant) is ever stored to
  /// this global, keep track of what value it is.
  Value *StoredOnceValue = nullptr;
  /// this global, keep track of what value it is via the store instruction.
  const StoreInst *StoredOnceStore = nullptr;

  /// If only one value (besides the initializer constant) is ever stored to
  /// this global return the stored value.
  Value *getStoredOnceValue() const {
    return (StoredType == StoredOnce && StoredOnceStore)
               ? StoredOnceStore->getOperand(0)
               : nullptr;
  }

  /// These start out null/false.  When the first accessing function is noticed,
  /// it is recorded. When a second different accessing function is noticed,
+5 −0
Original line number Diff line number Diff line
@@ -259,6 +259,11 @@ bool TargetTransformInfo::isNoopAddrSpaceCast(unsigned FromAS,
  return TTIImpl->isNoopAddrSpaceCast(FromAS, ToAS);
}

bool TargetTransformInfo::canHaveNonUndefGlobalInitializerInAddressSpace(
    unsigned AS) const {
  return TTIImpl->canHaveNonUndefGlobalInitializerInAddressSpace(AS);
}

unsigned TargetTransformInfo::getAssumedAddrSpace(const Value *V) const {
  return TTIImpl->getAssumedAddrSpace(V);
}
+6 −0
Original line number Diff line number Diff line
@@ -182,6 +182,12 @@ public:

  bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
                                  Intrinsic::ID IID) const;

  bool canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const {
    return AS != AMDGPUAS::LOCAL_ADDRESS && AS != AMDGPUAS::REGION_ADDRESS &&
           AS != AMDGPUAS::PRIVATE_ADDRESS;
  }

  Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
                                          Value *NewV) const;

Loading