clang-format all the GC related files (NFC)
authorPhilip Reames <listmail@philipreames.com>
Fri, 16 Jan 2015 23:16:12 +0000 (23:16 +0000)
committerPhilip Reames <listmail@philipreames.com>
Fri, 16 Jan 2015 23:16:12 +0000 (23:16 +0000)
Nothing interesting here...

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226342 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/CodeGen/GCMetadata.h
include/llvm/CodeGen/GCMetadataPrinter.h
include/llvm/CodeGen/GCs.h
include/llvm/IR/GCStrategy.h
lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
lib/CodeGen/ErlangGC.cpp
lib/CodeGen/GCMetadata.cpp
lib/CodeGen/GCMetadataPrinter.cpp
lib/CodeGen/GCRootLowering.cpp
lib/CodeGen/OcamlGC.cpp
lib/CodeGen/ShadowStackGC.cpp
lib/CodeGen/StatepointExampleGC.cpp
lib/IR/GCStrategy.cpp

index 6922b70bd9a4c3c82294cc0c08dcc25605990546..19aa0b031f36dd90c14a17b95fc23e9aa9c1c496 100644 (file)
 #include <memory>
 
 namespace llvm {
-  class AsmPrinter;
-  class Constant;
-  class MCSymbol;
+class AsmPrinter;
+class Constant;
+class MCSymbol;
+
+/// GCPoint - Metadata for a collector-safe point in machine code.
+///
+struct GCPoint {
+  GC::PointKind Kind; ///< The kind of the safe point.
+  MCSymbol *Label;    ///< A label.
+  DebugLoc Loc;
+
+  GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL)
+      : Kind(K), Label(L), Loc(DL) {}
+};
+
+/// GCRoot - Metadata for a pointer to an object managed by the garbage
+/// collector.
+struct GCRoot {
+  int Num;                  ///< Usually a frame index.
+  int StackOffset;          ///< Offset from the stack pointer.
+  const Constant *Metadata; ///< Metadata straight from the call
+                            ///< to llvm.gcroot.
+
+  GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
+};
+
+/// Garbage collection metadata for a single function.  Currently, this
+/// information only applies to GCStrategies which use GCRoot.
+class GCFunctionInfo {
+public:
+  typedef std::vector<GCPoint>::iterator iterator;
+  typedef std::vector<GCRoot>::iterator roots_iterator;
+  typedef std::vector<GCRoot>::const_iterator live_iterator;
+
+private:
+  const Function &F;
+  GCStrategy &S;
+  uint64_t FrameSize;
+  std::vector<GCRoot> Roots;
+  std::vector<GCPoint> SafePoints;
+
+  // FIXME: Liveness. A 2D BitVector, perhaps?
+  //
+  //   BitVector Liveness;
+  //
+  //   bool islive(int point, int root) =
+  //     Liveness[point * SafePoints.size() + root]
+  //
+  // The bit vector is the more compact representation where >3.2% of roots
+  // are live per safe point (1.5% on 64-bit hosts).
+
+public:
+  GCFunctionInfo(const Function &F, GCStrategy &S);
+  ~GCFunctionInfo();
+
+  /// getFunction - Return the function to which this metadata applies.
+  ///
+  const Function &getFunction() const { return F; }
+
+  /// getStrategy - Return the GC strategy for the function.
+  ///
+  GCStrategy &getStrategy() { return S; }
+
+  /// addStackRoot - Registers a root that lives on the stack. Num is the
+  ///                stack object ID for the alloca (if the code generator is
+  //                 using  MachineFrameInfo).
+  void addStackRoot(int Num, const Constant *Metadata) {
+    Roots.push_back(GCRoot(Num, Metadata));
+  }
+
+  /// removeStackRoot - Removes a root.
+  roots_iterator removeStackRoot(roots_iterator position) {
+    return Roots.erase(position);
+  }
+
+  /// addSafePoint - Notes the existence of a safe point. Num is the ID of the
+  /// label just prior to the safe point (if the code generator is using
+  /// MachineModuleInfo).
+  void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) {
+    SafePoints.push_back(GCPoint(Kind, Label, DL));
+  }
+
+  /// getFrameSize/setFrameSize - Records the function's frame size.
+  ///
+  uint64_t getFrameSize() const { return FrameSize; }
+  void setFrameSize(uint64_t S) { FrameSize = S; }
+
+  /// begin/end - Iterators for safe points.
+  ///
+  iterator begin() { return SafePoints.begin(); }
+  iterator end() { return SafePoints.end(); }
+  size_t size() const { return SafePoints.size(); }
+
+  /// roots_begin/roots_end - Iterators for all roots in the function.
+  ///
+  roots_iterator roots_begin() { return Roots.begin(); }
+  roots_iterator roots_end() { return Roots.end(); }
+  size_t roots_size() const { return Roots.size(); }
 
-  /// GCPoint - Metadata for a collector-safe point in machine code.
+  /// live_begin/live_end - Iterators for live roots at a given safe point.
   ///
-  struct GCPoint {
-    GC::PointKind Kind; ///< The kind of the safe point.
-    MCSymbol *Label;    ///< A label.
-    DebugLoc Loc;
-
-    GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL)
-        : Kind(K), Label(L), Loc(DL) {}
-  };
-
-  /// GCRoot - Metadata for a pointer to an object managed by the garbage
-  /// collector.
-  struct GCRoot {
-    int Num;            ///< Usually a frame index.
-    int StackOffset;    ///< Offset from the stack pointer.
-    const Constant *Metadata; ///< Metadata straight from the call
-                              ///< to llvm.gcroot.
-
-    GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
-  };
-
-
-  /// Garbage collection metadata for a single function.  Currently, this
-  /// information only applies to GCStrategies which use GCRoot.
-  class GCFunctionInfo {
-  public:
-    typedef std::vector<GCPoint>::iterator iterator;
-    typedef std::vector<GCRoot>::iterator roots_iterator;
-    typedef std::vector<GCRoot>::const_iterator live_iterator;
-
-  private:
-    const Function &F;
-    GCStrategy &S;
-    uint64_t FrameSize;
-    std::vector<GCRoot> Roots;
-    std::vector<GCPoint> SafePoints;
-
-    // FIXME: Liveness. A 2D BitVector, perhaps?
-    //
-    //   BitVector Liveness;
-    //
-    //   bool islive(int point, int root) =
-    //     Liveness[point * SafePoints.size() + root]
-    //
-    // The bit vector is the more compact representation where >3.2% of roots
-    // are live per safe point (1.5% on 64-bit hosts).
-
-  public:
-    GCFunctionInfo(const Function &F, GCStrategy &S);
-    ~GCFunctionInfo();
-
-    /// getFunction - Return the function to which this metadata applies.
-    ///
-    const Function &getFunction() const { return F; }
-
-    /// getStrategy - Return the GC strategy for the function.
-    ///
-    GCStrategy &getStrategy() { return S; }
-
-    /// addStackRoot - Registers a root that lives on the stack. Num is the
-    ///                stack object ID for the alloca (if the code generator is
-    //                 using  MachineFrameInfo).
-    void addStackRoot(int Num, const Constant *Metadata) {
-      Roots.push_back(GCRoot(Num, Metadata));
-    }
-
-    /// removeStackRoot - Removes a root.
-    roots_iterator removeStackRoot(roots_iterator position) {
-      return Roots.erase(position);
-    }
-
-    /// addSafePoint - Notes the existence of a safe point. Num is the ID of the
-    /// label just prior to the safe point (if the code generator is using
-    /// MachineModuleInfo).
-    void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) {
-      SafePoints.push_back(GCPoint(Kind, Label, DL));
-    }
-
-    /// getFrameSize/setFrameSize - Records the function's frame size.
-    ///
-    uint64_t getFrameSize() const { return FrameSize; }
-    void setFrameSize(uint64_t S) { FrameSize = S; }
-
-    /// begin/end - Iterators for safe points.
-    ///
-    iterator begin() { return SafePoints.begin(); }
-    iterator end()   { return SafePoints.end();   }
-    size_t size() const { return SafePoints.size(); }
-
-    /// roots_begin/roots_end - Iterators for all roots in the function.
-    ///
-    roots_iterator roots_begin() { return Roots.begin(); }
-    roots_iterator roots_end  () { return Roots.end();   }
-    size_t roots_size() const { return Roots.size(); }
-
-    /// live_begin/live_end - Iterators for live roots at a given safe point.
-    ///
-    live_iterator live_begin(const iterator &p) { return roots_begin(); }
-    live_iterator live_end  (const iterator &p) { return roots_end();   }
-    size_t live_size(const iterator &p) const { return roots_size(); }
-  };
-
-  /// An analysis pass which caches information about the entire Module.
-  /// Records both the function level information used by GCRoots and a
-  /// cache of the 'active' gc strategy objects for the current Module.
-  class GCModuleInfo : public ImmutablePass {
-    /// A list of GCStrategies which are active in this Module.  These are
-    /// not owning pointers.
-    std::vector<GCStrategy*> StrategyList;
-  public:
-    /// List of per function info objects.  In theory, Each of these
-    /// may be associated with a different GC.
-    typedef std::vector<std::unique_ptr<GCFunctionInfo>> FuncInfoVec;
-
-    FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); }
-    FuncInfoVec::iterator funcinfo_end()   { return Functions.end();   }
-    
-
-  private:
-    /// Owning list of all GCFunctionInfos associated with this Module
-    FuncInfoVec Functions;
-
-    /// Non-owning map to bypass linear search when finding the GCFunctionInfo
-    /// associated with a particular Function.
-    typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type;
-    finfo_map_type FInfoMap;
-  public:
-
-    typedef std::vector<GCStrategy*>::const_iterator iterator;
-
-    static char ID;
-
-    GCModuleInfo();
-
-    /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should
-    /// call it in doFinalization().
-    ///
-    void clear();
-
-    /// begin/end - Iterators for used strategies.
-    ///
-    iterator begin() const { return StrategyList.begin(); }
-    iterator end()   const { return StrategyList.end();   }
-
-    /// get - Look up function metadata.  This is currently assumed
-    /// have the side effect of initializing the associated GCStrategy.  That
-    /// will soon change.
-    GCFunctionInfo &getFunctionInfo(const Function &F);
-  };
+  live_iterator live_begin(const iterator &p) { return roots_begin(); }
+  live_iterator live_end(const iterator &p) { return roots_end(); }
+  size_t live_size(const iterator &p) const { return roots_size(); }
+};
+
+/// An analysis pass which caches information about the entire Module.
+/// Records both the function level information used by GCRoots and a
+/// cache of the 'active' gc strategy objects for the current Module.
+class GCModuleInfo : public ImmutablePass {
+  /// A list of GCStrategies which are active in this Module.  These are
+  /// not owning pointers.
+  std::vector<GCStrategy *> StrategyList;
+
+public:
+  /// List of per function info objects.  In theory, Each of these
+  /// may be associated with a different GC.
+  typedef std::vector<std::unique_ptr<GCFunctionInfo>> FuncInfoVec;
 
+  FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); }
+  FuncInfoVec::iterator funcinfo_end() { return Functions.end(); }
+
+private:
+  /// Owning list of all GCFunctionInfos associated with this Module
+  FuncInfoVec Functions;
+
+  /// Non-owning map to bypass linear search when finding the GCFunctionInfo
+  /// associated with a particular Function.
+  typedef DenseMap<const Function *, GCFunctionInfo *> finfo_map_type;
+  finfo_map_type FInfoMap;
+
+public:
+  typedef std::vector<GCStrategy *>::const_iterator iterator;
+
+  static char ID;
+
+  GCModuleInfo();
+
+  /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should
+  /// call it in doFinalization().
+  ///
+  void clear();
+
+  /// begin/end - Iterators for used strategies.
+  ///
+  iterator begin() const { return StrategyList.begin(); }
+  iterator end() const { return StrategyList.end(); }
+
+  /// get - Look up function metadata.  This is currently assumed
+  /// have the side effect of initializing the associated GCStrategy.  That
+  /// will soon change.
+  GCFunctionInfo &getFunctionInfo(const Function &F);
+};
 }
 
 #endif
index 6010cb8a4f3de00cbe34fae8ffcfefe92b2cbcfd..3e7d64cd15c0dd0aecc543539c23688f977cba9c 100644 (file)
 
 namespace llvm {
 
-  class GCMetadataPrinter;
+class GCMetadataPrinter;
 
-  /// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
-  /// defaults from Registry.
-  typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
+/// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
+/// defaults from Registry.
+typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
 
-  /// GCMetadataPrinter - Emits GC metadata as assembly code.  Instances are
-  /// created, managed, and owned by the AsmPrinter.
-  class GCMetadataPrinter {
-  private:
-    GCStrategy *S;
-    friend class AsmPrinter;
+/// GCMetadataPrinter - Emits GC metadata as assembly code.  Instances are
+/// created, managed, and owned by the AsmPrinter.
+class GCMetadataPrinter {
+private:
+  GCStrategy *S;
+  friend class AsmPrinter;
 
-  protected:
-    // May only be subclassed.
-    GCMetadataPrinter();
+protected:
+  // May only be subclassed.
+  GCMetadataPrinter();
 
-  private:
-    GCMetadataPrinter(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
-    GCMetadataPrinter &
-      operator=(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
+private:
+  GCMetadataPrinter(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
+  GCMetadataPrinter &operator=(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
 
-  public:
-    GCStrategy &getStrategy() { return *S; }
+public:
+  GCStrategy &getStrategy() { return *S; }
 
-    /// Called before the assembly for the module is generated by
-    /// the AsmPrinter (but after target specific hooks.)
-    virtual void beginAssembly(Module &M, GCModuleInfo &Info,
-                               AsmPrinter &AP) {}
-    /// Called after the assembly for the module is generated by
-    /// the AsmPrinter (but before target specific hooks)
-    virtual void finishAssembly(Module &M, GCModuleInfo &Info,
-                                AsmPrinter &AP) {}
-
-    virtual ~GCMetadataPrinter();
-  };
+  /// Called before the assembly for the module is generated by
+  /// the AsmPrinter (but after target specific hooks.)
+  virtual void beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+  /// Called after the assembly for the module is generated by
+  /// the AsmPrinter (but before target specific hooks)
+  virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
 
+  virtual ~GCMetadataPrinter();
+};
 }
 
 #endif
index 51a31842a5c00bca5ba1a1d4ce25619b42245183..5bae41ea03057d5434799b09a039f4276199f844 100644 (file)
 #define LLVM_CODEGEN_GCS_H
 
 namespace llvm {
-  class GCStrategy;
-  class GCMetadataPrinter;
+class GCStrategy;
+class GCMetadataPrinter;
 
-  /// FIXME: Collector instances are not useful on their own. These no longer
-  ///        serve any purpose except to link in the plugins.
+/// FIXME: Collector instances are not useful on their own. These no longer
+///        serve any purpose except to link in the plugins.
 
-  /// Creates an ocaml-compatible garbage collector.
-  void linkOcamlGC();
+/// Creates an ocaml-compatible garbage collector.
+void linkOcamlGC();
 
-  /// Creates an ocaml-compatible metadata printer.
-  void linkOcamlGCPrinter();
+/// Creates an ocaml-compatible metadata printer.
+void linkOcamlGCPrinter();
 
-  /// Creates an erlang-compatible garbage collector.
-  void linkErlangGC();
+/// Creates an erlang-compatible garbage collector.
+void linkErlangGC();
 
-  /// Creates an erlang-compatible metadata printer.
-  void linkErlangGCPrinter();
+/// Creates an erlang-compatible metadata printer.
+void linkErlangGCPrinter();
 
-  /// Creates a shadow stack garbage collector. This collector requires no code
-  /// generator support.
-  void linkShadowStackGC();
+/// Creates a shadow stack garbage collector. This collector requires no code
+/// generator support.
+void linkShadowStackGC();
 
-  void linkStatepointExampleGC();
+void linkStatepointExampleGC();
 }
 
 #endif
index 1cd107b3bcaaacdcf24c3723929e26a80e30dc39..15acfe443cd7364c8da0ff8495e928d607ccdec3 100644 (file)
 // GCStrategy is relevant for implementations using either gc.root or
 // gc.statepoint based lowering strategies, but is currently focused mostly on
 // options for gc.root.  This will change over time.
-// 
+//
 // When requested by a subclass of GCStrategy, the gc.root implementation will
 // populate GCModuleInfo and GCFunctionInfo with that about each Function in
 // the Module that opts in to garbage collection.  Specifically:
-// 
+//
 // - Safe points
 //   Garbage collection is generally only possible at certain points in code.
 //   GCStrategy can request that the collector insert such points:
@@ -28,7 +28,7 @@
 //     - At and after any call to a subroutine
 //     - Before returning from the current function
 //     - Before backwards branches (loops)
-// 
+//
 // - Roots
 //   When a reference to a GC-allocated object exists on the stack, it must be
 //   stored in an alloca registered with llvm.gcoot.
@@ -42,7 +42,7 @@
 // insertion support is planned.  gc.statepoint does not currently support
 // custom stack map formats; such can be generated by parsing the standard
 // stack map section if desired.
-// 
+//
 // The read and write barrier support can be used with either implementation.
 //
 //===----------------------------------------------------------------------===//
 #include <string>
 
 namespace llvm {
-  namespace GC {
-    /// PointKind - The type of a collector-safe point.
-    ///
-    enum PointKind {
-      Loop,    ///< Instr is a loop (backwards branch).
-      Return,  ///< Instr is a return instruction.
-      PreCall, ///< Instr is a call instruction.
-      PostCall ///< Instr is the return address of a call.
-    };
+namespace GC {
+/// PointKind - The type of a collector-safe point.
+///
+enum PointKind {
+  Loop,    ///< Instr is a loop (backwards branch).
+  Return,  ///< Instr is a return instruction.
+  PreCall, ///< Instr is a call instruction.
+  PostCall ///< Instr is the return address of a call.
+};
+}
+
+/// GCStrategy describes a garbage collector algorithm's code generation
+/// requirements, and provides overridable hooks for those needs which cannot
+/// be abstractly described.  GCStrategy objects must be looked up through
+/// the Function.  The objects themselves are owned by the Context and must
+/// be immutable.
+class GCStrategy {
+private:
+  std::string Name;
+  friend class LLVMContextImpl;
+
+protected:
+  bool UseStatepoints; /// Uses gc.statepoints as opposed to gc.roots,
+                       /// if set, none of the other options can be
+                       /// anything but their default values.
+
+  unsigned NeededSafePoints; ///< Bitmask of required safe points.
+  bool CustomReadBarriers;   ///< Default is to insert loads.
+  bool CustomWriteBarriers;  ///< Default is to insert stores.
+  bool CustomRoots;          ///< Default is to pass through to backend.
+  bool InitRoots;            ///< If set, roots are nulled during lowering.
+  bool UsesMetadata;         ///< If set, backend must emit metadata tables.
+
+public:
+  GCStrategy();
+  virtual ~GCStrategy() {}
+
+  /// Return the name of the GC strategy.  This is the value of the collector
+  /// name string specified on functions which use this strategy.
+  const std::string &getName() const { return Name; }
+
+  /// By default, write barriers are replaced with simple store
+  /// instructions. If true, then performCustomLowering must instead lower
+  /// them.
+  bool customWriteBarrier() const { return CustomWriteBarriers; }
+
+  /// By default, read barriers are replaced with simple load
+  /// instructions. If true, then performCustomLowering must instead lower
+  /// them.
+  bool customReadBarrier() const { return CustomReadBarriers; }
+
+  /// Returns true if this strategy is expecting the use of gc.statepoints,
+  /// and false otherwise.
+  bool useStatepoints() const { return UseStatepoints; }
+
+  /** @name Statepoint Specific Properties */
+  ///@{
+
+  /// If the value specified can be reliably distinguished, returns true for
+  /// pointers to GC managed locations and false for pointers to non-GC
+  /// managed locations.  Note a GCStrategy can always return 'None' (i.e. an
+  /// empty optional indicating it can't reliably distinguish.
+  virtual Optional<bool> isGCManagedPointer(const Value *V) const {
+    return None;
+  }
+  ///@}
+
+  /** @name GCRoot Specific Properties
+   * These properties and overrides only apply to collector strategies using
+   * GCRoot.
+   */
+  ///@{
+
+  /// True if safe points of any kind are required. By default, none are
+  /// recorded.
+  bool needsSafePoints() const { return NeededSafePoints != 0; }
+
+  /// True if the given kind of safe point is required. By default, none are
+  /// recorded.
+  bool needsSafePoint(GC::PointKind Kind) const {
+    return (NeededSafePoints & 1 << Kind) != 0;
+  }
+
+  /// By default, roots are left for the code generator so it can generate a
+  /// stack map. If true, then performCustomLowering must delete them.
+  bool customRoots() const { return CustomRoots; }
+
+  /// If set, gcroot intrinsics should initialize their allocas to null
+  /// before the first use. This is necessary for most GCs and is enabled by
+  /// default.
+  bool initializeRoots() const { return InitRoots; }
+
+  /// If set, appropriate metadata tables must be emitted by the back-end
+  /// (assembler, JIT, or otherwise). For statepoint, this method is
+  /// currently unsupported.  The stackmap information can be found in the
+  /// StackMap section as described in the documentation.
+  bool usesMetadata() const { return UsesMetadata; }
+
+  ///@}
+
+  /// initializeCustomLowering/performCustomLowering - If any of the actions
+  /// are set to custom, performCustomLowering must be overriden to transform
+  /// the corresponding actions to LLVM IR. initializeCustomLowering is
+  /// optional to override. These are the only GCStrategy methods through
+  /// which the LLVM IR can be modified.  These methods apply mostly to
+  /// gc.root based implementations, but can be overriden to provide custom
+  /// barrier lowerings with gc.statepoint as well.
+  ///@{
+  virtual bool initializeCustomLowering(Module &F) {
+    // No changes made
+    return false;
+  }
+  virtual bool performCustomLowering(Function &F) {
+    llvm_unreachable("GCStrategy subclass specified a configuration which"
+                     "requires a custom lowering without providing one");
   }
+};
 
-  
-  /// GCStrategy describes a garbage collector algorithm's code generation
-  /// requirements, and provides overridable hooks for those needs which cannot
-  /// be abstractly described.  GCStrategy objects must be looked up through
-  /// the Function.  The objects themselves are owned by the Context and must
-  /// be immutable.
-  class GCStrategy {
-  private:
-    std::string Name;
-    friend class LLVMContextImpl;
-    
-  protected:
-    bool UseStatepoints;       /// Uses gc.statepoints as opposed to gc.roots,
-                               /// if set, none of the other options can be
-                               /// anything but their default values.
-
-    unsigned NeededSafePoints; ///< Bitmask of required safe points.
-    bool CustomReadBarriers;   ///< Default is to insert loads.
-    bool CustomWriteBarriers;  ///< Default is to insert stores.
-    bool CustomRoots;          ///< Default is to pass through to backend.
-    bool InitRoots;            ///< If set, roots are nulled during lowering.
-    bool UsesMetadata;         ///< If set, backend must emit metadata tables.
-    
-  public:
-    GCStrategy();
-    virtual ~GCStrategy() {}
-    
-    /// Return the name of the GC strategy.  This is the value of the collector
-    /// name string specified on functions which use this strategy.
-    const std::string &getName() const { return Name; }
-
-    /// By default, write barriers are replaced with simple store
-    /// instructions. If true, then performCustomLowering must instead lower
-    /// them. 
-    bool customWriteBarrier() const { return CustomWriteBarriers; }
-    
-    /// By default, read barriers are replaced with simple load
-    /// instructions. If true, then performCustomLowering must instead lower
-    /// them. 
-    bool customReadBarrier() const { return CustomReadBarriers; }
-
-    /// Returns true if this strategy is expecting the use of gc.statepoints,
-    /// and false otherwise.
-    bool useStatepoints() const { return UseStatepoints; }
-
-    /** @name Statepoint Specific Properties */
-    ///@{
-
-    /// If the value specified can be reliably distinguished, returns true for
-    /// pointers to GC managed locations and false for pointers to non-GC 
-    /// managed locations.  Note a GCStrategy can always return 'None' (i.e. an
-    /// empty optional indicating it can't reliably distinguish.   
-    virtual Optional<bool> isGCManagedPointer(const Value *V) const {
-      return None;
-    }
-    ///@}
-
-    /** @name GCRoot Specific Properties
-     * These properties and overrides only apply to collector strategies using
-     * GCRoot. 
-     */
-    ///@{
-
-    /// True if safe points of any kind are required. By default, none are
-    /// recorded. 
-    bool needsSafePoints() const {
-      return NeededSafePoints != 0;
-    }
-    
-    /// True if the given kind of safe point is required. By default, none are
-    /// recorded. 
-    bool needsSafePoint(GC::PointKind Kind) const {
-      return (NeededSafePoints & 1 << Kind) != 0;
-    }
-        
-    /// By default, roots are left for the code generator so it can generate a
-    /// stack map. If true, then performCustomLowering must delete them.
-    bool customRoots() const { return CustomRoots; }
-
-    /// If set, gcroot intrinsics should initialize their allocas to null
-    /// before the first use. This is necessary for most GCs and is enabled by
-    /// default. 
-    bool initializeRoots() const { return InitRoots; }
-    
-    /// If set, appropriate metadata tables must be emitted by the back-end
-    /// (assembler, JIT, or otherwise). For statepoint, this method is
-    /// currently unsupported.  The stackmap information can be found in the
-    /// StackMap section as described in the documentation.
-    bool usesMetadata() const { return UsesMetadata; }
-
-    ///@}
-    
-    /// initializeCustomLowering/performCustomLowering - If any of the actions
-    /// are set to custom, performCustomLowering must be overriden to transform
-    /// the corresponding actions to LLVM IR. initializeCustomLowering is
-    /// optional to override. These are the only GCStrategy methods through
-    /// which the LLVM IR can be modified.  These methods apply mostly to
-    /// gc.root based implementations, but can be overriden to provide custom
-    /// barrier lowerings with gc.statepoint as well.
-    ///@{
-    virtual bool initializeCustomLowering(Module &F) {
-      // No changes made
-      return false;
-    }
-    virtual bool performCustomLowering(Function &F) {
-      llvm_unreachable("GCStrategy subclass specified a configuration which"
-                       "requires a custom lowering without providing one");
-    }
-  };
-
-  /// Subclasses of GCStrategy are made available for use during compilation by
-  /// adding them to the global GCRegistry.  This can done either within the
-  /// LLVM source tree or via a loadable plugin.  An example registeration
-  /// would be:
-  /// static GCRegistry::Add<CustomGC> X("custom-name",
-  ///        "my custom supper fancy gc strategy");
-  /// 
-  /// Note that to use a custom GCMetadataPrinter w/gc.roots, you must also
-  /// register your GCMetadataPrinter subclass with the
-  /// GCMetadataPrinterRegistery as well. 
-  typedef Registry<GCStrategy> GCRegistry;
+/// Subclasses of GCStrategy are made available for use during compilation by
+/// adding them to the global GCRegistry.  This can done either within the
+/// LLVM source tree or via a loadable plugin.  An example registeration
+/// would be:
+/// static GCRegistry::Add<CustomGC> X("custom-name",
+///        "my custom supper fancy gc strategy");
+///
+/// Note that to use a custom GCMetadataPrinter w/gc.roots, you must also
+/// register your GCMetadataPrinter subclass with the
+/// GCMetadataPrinterRegistery as well.
+typedef Registry<GCStrategy> GCRegistry;
 }
 
 #endif
index e293acd43a88eaed83d5597c23931c086c2f66b5..aa4418f6a754949b83aa2ce2acd40c0b8bfb84cf 100644 (file)
@@ -34,18 +34,16 @@ using namespace llvm;
 
 namespace {
 
-  class ErlangGCPrinter : public GCMetadataPrinter {
-  public:
-    void finishAssembly(Module &M, GCModuleInfo &Info,
-                        AsmPrinter &AP) override;
-  };
-
+class ErlangGCPrinter : public GCMetadataPrinter {
+public:
+  void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) override;
+};
 }
 
 static GCMetadataPrinterRegistry::Add<ErlangGCPrinter>
-X("erlang", "erlang-compatible garbage collector");
+    X("erlang", "erlang-compatible garbage collector");
 
-void llvm::linkErlangGCPrinter() { }
+void llvm::linkErlangGCPrinter() {}
 
 void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
                                      AsmPrinter &AP) {
@@ -54,13 +52,13 @@ void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
       AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSize();
 
   // Put this in a custom .note section.
-  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getContext()
-    .getELFSection(".note.gc", ELF::SHT_PROGBITS, 0,
-                   SectionKind::getDataRel()));
+  AP.OutStreamer.SwitchSection(
+      AP.getObjFileLowering().getContext().getELFSection(
+          ".note.gc", ELF::SHT_PROGBITS, 0, SectionKind::getDataRel()));
 
   // For each function...
   for (GCModuleInfo::FuncInfoVec::iterator FI = Info.funcinfo_begin(),
-         IE = Info.funcinfo_end();
+                                           IE = Info.funcinfo_end();
        FI != IE; ++FI) {
     GCFunctionInfo &MD = **FI;
     if (MD.getStrategy().getName() != getStrategy().getName())
@@ -91,7 +89,7 @@ void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
       // Emit the address of the safe point.
       OS.AddComment("safe point address");
       MCSymbol *Label = PI->Label;
-      AP.EmitLabelPlusOffset(Label/*Hi*/, 0/*Offset*/, 4/*Size*/);
+      AP.EmitLabelPlusOffset(Label /*Hi*/, 0 /*Offset*/, 4 /*Size*/);
     }
 
     // Stack information never change in safe points! Only print info from the
@@ -104,8 +102,9 @@ void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
 
     // Emit stack arity, i.e. the number of stacked arguments.
     unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6;
-    unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs ?
-                          MD.getFunction().arg_size() - RegisteredArgs : 0;
+    unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs
+                              ? MD.getFunction().arg_size() - RegisteredArgs
+                              : 0;
     OS.AddComment("stack arity");
     AP.EmitInt16(StackArity);
 
@@ -116,7 +115,7 @@ void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
     // And for each live root...
     for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI),
                                        LE = MD.live_end(PI);
-                                       LI != LE; ++LI) {
+         LI != LE; ++LI) {
       // Emit live root's offset within the stack frame.
       OS.AddComment("stack index (offset / wordsize)");
       AP.EmitInt16(LI->StackOffset / IntPtrSize);
index ddb14a05736358eef6d3754f90e1a3723896044b..d6822aa42a3e42fc78d0c5c9d66cd0a1f0d788b9 100644 (file)
@@ -32,20 +32,17 @@ using namespace llvm;
 
 namespace {
 
-  class OcamlGCMetadataPrinter : public GCMetadataPrinter {
-  public:
-    void beginAssembly(Module &M, GCModuleInfo &Info,
-                       AsmPrinter &AP) override;
-    void finishAssembly(Module &M, GCModuleInfo &Info,
-                        AsmPrinter &AP) override;
-  };
-
+class OcamlGCMetadataPrinter : public GCMetadataPrinter {
+public:
+  void beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) override;
+  void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) override;
+};
 }
 
 static GCMetadataPrinterRegistry::Add<OcamlGCMetadataPrinter>
-Y("ocaml", "ocaml 3.10-compatible collector");
+    Y("ocaml", "ocaml 3.10-compatible collector");
 
-void llvm::linkOcamlGCPrinter() { }
+void llvm::linkOcamlGCPrinter() {}
 
 static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) {
   const std::string &MId = M.getModuleIdentifier();
@@ -113,7 +110,8 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
 
   int NumDescriptors = 0;
   for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(),
-         IE = Info.funcinfo_end(); I != IE; ++I) {
+                                           IE = Info.funcinfo_end();
+       I != IE; ++I) {
     GCFunctionInfo &FI = **I;
     if (FI.getStrategy().getName() != getStrategy().getName())
       // this function is managed by some other GC
@@ -123,7 +121,7 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
     }
   }
 
-  if (NumDescriptors >= 1<<16) {
+  if (NumDescriptors >= 1 << 16) {
     // Very rude!
     report_fatal_error(" Too much descriptor for ocaml GC");
   }
@@ -131,19 +129,22 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
   AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
 
   for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(),
-         IE = Info.funcinfo_end(); I != IE; ++I) {
+                                           IE = Info.funcinfo_end();
+       I != IE; ++I) {
     GCFunctionInfo &FI = **I;
     if (FI.getStrategy().getName() != getStrategy().getName())
       // this function is managed by some other GC
       continue;
 
     uint64_t FrameSize = FI.getFrameSize();
-    if (FrameSize >= 1<<16) {
+    if (FrameSize >= 1 << 16) {
       // Very rude!
       report_fatal_error("Function '" + FI.getFunction().getName() +
                          "' is too large for the ocaml GC! "
-                         "Frame size " + Twine(FrameSize) + ">= 65536.\n"
-                         "(" + Twine(uintptr_t(&FI)) + ")");
+                         "Frame size " +
+                         Twine(FrameSize) + ">= 65536.\n"
+                                            "(" +
+                         Twine(uintptr_t(&FI)) + ")");
     }
 
     AP.OutStreamer.AddComment("live roots for " +
@@ -152,11 +153,12 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
 
     for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
       size_t LiveCount = FI.live_size(J);
-      if (LiveCount >= 1<<16) {
+      if (LiveCount >= 1 << 16) {
         // Very rude!
         report_fatal_error("Function '" + FI.getFunction().getName() +
                            "' is too large for the ocaml GC! "
-                           "Live root count "+Twine(LiveCount)+" >= 65536.");
+                           "Live root count " +
+                           Twine(LiveCount) + " >= 65536.");
       }
 
       AP.OutStreamer.EmitSymbolValue(J->Label, IntPtrSize);
@@ -164,12 +166,13 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
       AP.EmitInt16(LiveCount);
 
       for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
-                                         KE = FI.live_end(J); K != KE; ++K) {
-        if (K->StackOffset >= 1<<16) {
+                                         KE = FI.live_end(J);
+           K != KE; ++K) {
+        if (K->StackOffset >= 1 << 16) {
           // Very rude!
           report_fatal_error(
-                 "GC root stack offset is outside of fixed stack frame and out "
-                 "of range for ocaml GC!");
+              "GC root stack offset is outside of fixed stack frame and out "
+              "of range for ocaml GC!");
         }
         AP.EmitInt16(K->StackOffset);
       }
index ec2c2e8daf23715e9cb038aa1a18229bb51ec838..30af07f12141ad1f6b11e5ca56ef7d8e1c03b2ac 100644 (file)
@@ -27,17 +27,16 @@ using namespace llvm;
 
 namespace {
 
-  class ErlangGC : public GCStrategy {
-  public:
-    ErlangGC();
-  };
-
+class ErlangGC : public GCStrategy {
+public:
+  ErlangGC();
+};
 }
 
-static GCRegistry::Add<ErlangGC>
-X("erlang", "erlang-compatible garbage collector");
+static GCRegistry::Add<ErlangGC> X("erlang",
+                                   "erlang-compatible garbage collector");
 
-void llvm::linkErlangGC() { }
+void llvm::linkErlangGC() {}
 
 ErlangGC::ErlangGC() {
   InitRoots = false;
index 6f4fa11d6d9fcd3df7388b6de3867ef93297be96..7a61d61e7d02c1556770b7c18c49ba48d93d242e 100644 (file)
 using namespace llvm;
 
 namespace {
-  
-  class Printer : public FunctionPass {
-    static char ID;
-    raw_ostream &OS;
-    
-  public:
-    explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {}
 
+class Printer : public FunctionPass {
+  static char ID;
+  raw_ostream &OS;
 
-    const char *getPassName() const override;
-    void getAnalysisUsage(AnalysisUsage &AU) const override;
+public:
+  explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {}
 
-    bool runOnFunction(Function &F) override;
-    bool doFinalization(Module &M) override;
-  };
+  const char *getPassName() const override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
 
+  bool runOnFunction(Function &F) override;
+  bool doFinalization(Module &M) override;
+};
 }
 
 INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
@@ -48,7 +46,7 @@ INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
 // -----------------------------------------------------------------------------
 
 GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)
-  : F(F), S(S), FrameSize(~0LL) {}
+    : F(F), S(S), FrameSize(~0LL) {}
 
 GCFunctionInfo::~GCFunctionInfo() {}
 
@@ -56,19 +54,18 @@ GCFunctionInfo::~GCFunctionInfo() {}
 
 char GCModuleInfo::ID = 0;
 
-GCModuleInfo::GCModuleInfo()
-    : ImmutablePass(ID) {
+GCModuleInfo::GCModuleInfo() : ImmutablePass(ID) {
   initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
 }
 
 GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
   assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
   assert(F.hasGC());
-  
+
   finfo_map_type::iterator I = FInfoMap.find(&F);
   if (I != FInfoMap.end())
     return *I->second;
-  
+
   GCStrategy *S = F.getGCStrategy();
   if (!S) {
     std::string error = std::string("unsupported GC: ") + F.getGC();
@@ -76,7 +73,7 @@ GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
   }
   // Save the fact this strategy is associated with this module.  Note that
   // these are non-owning references, the GCStrategy remains owned by the
-  // Context. 
+  // Context.
   StrategyList.push_back(S);
   Functions.push_back(make_unique<GCFunctionInfo>(F, *S));
   GCFunctionInfo *GFI = Functions.back().get();
@@ -98,7 +95,6 @@ FunctionPass *llvm::createGCInfoPrinter(raw_ostream &OS) {
   return new Printer(OS);
 }
 
-
 const char *Printer::getPassName() const {
   return "Print Garbage Collector Information";
 }
@@ -111,42 +107,49 @@ void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
 
 static const char *DescKind(GC::PointKind Kind) {
   switch (Kind) {
-    case GC::Loop:     return "loop";
-    case GC::Return:   return "return";
-    case GC::PreCall:  return "pre-call";
-    case GC::PostCall: return "post-call";
+  case GC::Loop:
+    return "loop";
+  case GC::Return:
+    return "return";
+  case GC::PreCall:
+    return "pre-call";
+  case GC::PostCall:
+    return "post-call";
   }
   llvm_unreachable("Invalid point kind");
 }
 
 bool Printer::runOnFunction(Function &F) {
-  if (F.hasGC()) return false;
-  
+  if (F.hasGC())
+    return false;
+
   GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
-  
+
   OS << "GC roots for " << FD->getFunction().getName() << ":\n";
   for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(),
-                                      RE = FD->roots_end(); RI != RE; ++RI)
+                                      RE = FD->roots_end();
+       RI != RE; ++RI)
     OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
-  
+
   OS << "GC safe points for " << FD->getFunction().getName() << ":\n";
-  for (GCFunctionInfo::iterator PI = FD->begin(),
-                                PE = FD->end(); PI != PE; ++PI) {
-    
-    OS << "\t" << PI->Label->getName() << ": "
-       << DescKind(PI->Kind) << ", live = {";
-    
+  for (GCFunctionInfo::iterator PI = FD->begin(), PE = FD->end(); PI != PE;
+       ++PI) {
+
+    OS << "\t" << PI->Label->getName() << ": " << DescKind(PI->Kind)
+       << ", live = {";
+
     for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI),
-                                       RE = FD->live_end(PI);;) {
+                                       RE = FD->live_end(PI);
+         ;) {
       OS << " " << RI->Num;
       if (++RI == RE)
         break;
       OS << ",";
     }
-    
+
     OS << " }\n";
   }
-  
+
   return false;
 }
 
index fdff4a78e07942bfa4efd7ef83061fae24a9246d..bb8cfa1cc809c33e7b09cf4566c0a4e64bcf4725 100644 (file)
@@ -14,6 +14,6 @@
 #include "llvm/CodeGen/GCMetadataPrinter.h"
 using namespace llvm;
 
-GCMetadataPrinter::GCMetadataPrinter() { }
+GCMetadataPrinter::GCMetadataPrinter() {}
 
-GCMetadataPrinter::~GCMetadataPrinter() { }
+GCMetadataPrinter::~GCMetadataPrinter() {}
index 8ff08ece76e41e485b63e76a899c38a2dfa1889c..7cb459874ef27146bf8279e60900b881ae899f75 100644 (file)
@@ -116,8 +116,6 @@ static bool NeedsCustomLoweringPass(const GCStrategy &C) {
   return C.customWriteBarrier() || C.customReadBarrier() || C.customRoots();
 }
 
-
-
 /// doInitialization - If this module uses the GC intrinsics, find them now.
 bool LowerIntrinsics::doInitialization(Module &M) {
   // FIXME: This is rather antisocial in the context of a JIT since it performs
@@ -139,7 +137,6 @@ bool LowerIntrinsics::doInitialization(Module &M) {
   return MadeChange;
 }
 
-
 /// CouldBecomeSafePoint - Predicate to conservatively determine whether the
 /// instruction could introduce a safe point.
 static bool CouldBecomeSafePoint(Instruction *I) {
@@ -199,7 +196,6 @@ static bool InsertRootInitializers(Function &F, AllocaInst **Roots,
   return MadeChange;
 }
 
-
 /// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores.
 /// Leave gcroot intrinsics; the code generator needs to see those.
 bool LowerIntrinsics::runOnFunction(Function &F) {
index c5c78529ece349b0e410d877617806bd0ef07ec9..164e3700909e41e270e267ff37929049a7601202 100644 (file)
 using namespace llvm;
 
 namespace {
-  class OcamlGC : public GCStrategy {
-  public:
-    OcamlGC();
-  };
+class OcamlGC : public GCStrategy {
+public:
+  OcamlGC();
+};
 }
 
-static GCRegistry::Add<OcamlGC>
-X("ocaml", "ocaml 3.10-compatible GC");
+static GCRegistry::Add<OcamlGC> X("ocaml", "ocaml 3.10-compatible GC");
 
-void llvm::linkOcamlGC() { }
+void llvm::linkOcamlGC() {}
 
 OcamlGC::OcamlGC() {
   NeededSafePoints = 1 << GC::PostCall;
index 181cb8c435c8584e9deb3a32a5e998719f7542b3..163d0efc07a81ef5c23f35dc42cb414d3ceba5a4 100644 (file)
@@ -39,161 +39,156 @@ using namespace llvm;
 
 namespace {
 
-  class ShadowStackGC : public GCStrategy {
-    /// RootChain - This is the global linked-list that contains the chain of GC
-    /// roots.
-    GlobalVariable *Head;
-
-    /// StackEntryTy - Abstract type of a link in the shadow stack.
-    ///
-    StructType *StackEntryTy;
-    StructType *FrameMapTy;
-
-    /// Roots - GC roots in the current function. Each is a pair of the
-    /// intrinsic call and its corresponding alloca.
-    std::vector<std::pair<CallInst*,AllocaInst*> > Roots;
-
-  public:
-    ShadowStackGC();
-
-    bool initializeCustomLowering(Module &M) override;
-    bool performCustomLowering(Function &F) override;
-
-  private:
-    bool IsNullValue(Value *V);
-    Constant *GetFrameMap(Function &F);
-    Type* GetConcreteStackEntryType(Function &F);
-    void CollectRoots(Function &F);
-    static GetElementPtrInst *CreateGEP(LLVMContext &Context, 
-                                        IRBuilder<> &B, Value *BasePtr,
-                                        int Idx1, const char *Name);
-    static GetElementPtrInst *CreateGEP(LLVMContext &Context,
-                                        IRBuilder<> &B, Value *BasePtr,
-                                        int Idx1, int Idx2, const char *Name);
-  };
+class ShadowStackGC : public GCStrategy {
+  /// RootChain - This is the global linked-list that contains the chain of GC
+  /// roots.
+  GlobalVariable *Head;
 
+  /// StackEntryTy - Abstract type of a link in the shadow stack.
+  ///
+  StructType *StackEntryTy;
+  StructType *FrameMapTy;
+
+  /// Roots - GC roots in the current function. Each is a pair of the
+  /// intrinsic call and its corresponding alloca.
+  std::vector<std::pair<CallInst *, AllocaInst *>> Roots;
+
+public:
+  ShadowStackGC();
+
+  bool initializeCustomLowering(Module &M) override;
+  bool performCustomLowering(Function &F) override;
+
+private:
+  bool IsNullValue(Value *V);
+  Constant *GetFrameMap(Function &F);
+  Type *GetConcreteStackEntryType(Function &F);
+  void CollectRoots(Function &F);
+  static GetElementPtrInst *CreateGEP(LLVMContext &Context, IRBuilder<> &B,
+                                      Value *BasePtr, int Idx1,
+                                      const char *Name);
+  static GetElementPtrInst *CreateGEP(LLVMContext &Context, IRBuilder<> &B,
+                                      Value *BasePtr, int Idx1, int Idx2,
+                                      const char *Name);
+};
 }
 
 static GCRegistry::Add<ShadowStackGC>
-X("shadow-stack", "Very portable GC for uncooperative code generators");
+    X("shadow-stack", "Very portable GC for uncooperative code generators");
 
 namespace {
-  /// EscapeEnumerator - This is a little algorithm to find all escape points
-  /// from a function so that "finally"-style code can be inserted. In addition
-  /// to finding the existing return and unwind instructions, it also (if
-  /// necessary) transforms any call instructions into invokes and sends them to
-  /// a landing pad.
-  ///
-  /// It's wrapped up in a state machine using the same transform C# uses for
-  /// 'yield return' enumerators, This transform allows it to be non-allocating.
-  class EscapeEnumerator {
-    Function &F;
-    const char *CleanupBBName;
-
-    // State.
-    int State;
-    Function::iterator StateBB, StateE;
-    IRBuilder<> Builder;
-
-  public:
-    EscapeEnumerator(Function &F, const char *N = "cleanup")
+/// EscapeEnumerator - This is a little algorithm to find all escape points
+/// from a function so that "finally"-style code can be inserted. In addition
+/// to finding the existing return and unwind instructions, it also (if
+/// necessary) transforms any call instructions into invokes and sends them to
+/// a landing pad.
+///
+/// It's wrapped up in a state machine using the same transform C# uses for
+/// 'yield return' enumerators, This transform allows it to be non-allocating.
+class EscapeEnumerator {
+  Function &F;
+  const char *CleanupBBName;
+
+  // State.
+  int State;
+  Function::iterator StateBB, StateE;
+  IRBuilder<> Builder;
+
+public:
+  EscapeEnumerator(Function &F, const char *N = "cleanup")
       : F(F), CleanupBBName(N), State(0), Builder(F.getContext()) {}
 
-    IRBuilder<> *Next() {
-      switch (State) {
-      default:
+  IRBuilder<> *Next() {
+    switch (State) {
+    default:
+      return nullptr;
+
+    case 0:
+      StateBB = F.begin();
+      StateE = F.end();
+      State = 1;
+
+    case 1:
+      // Find all 'return', 'resume', and 'unwind' instructions.
+      while (StateBB != StateE) {
+        BasicBlock *CurBB = StateBB++;
+
+        // Branches and invokes do not escape, only unwind, resume, and return
+        // do.
+        TerminatorInst *TI = CurBB->getTerminator();
+        if (!isa<ReturnInst>(TI) && !isa<ResumeInst>(TI))
+          continue;
+
+        Builder.SetInsertPoint(TI->getParent(), TI);
+        return &Builder;
+      }
+
+      State = 2;
+
+      // Find all 'call' instructions.
+      SmallVector<Instruction *, 16> Calls;
+      for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+        for (BasicBlock::iterator II = BB->begin(), EE = BB->end(); II != EE;
+             ++II)
+          if (CallInst *CI = dyn_cast<CallInst>(II))
+            if (!CI->getCalledFunction() ||
+                !CI->getCalledFunction()->getIntrinsicID())
+              Calls.push_back(CI);
+
+      if (Calls.empty())
         return nullptr;
 
-      case 0:
-        StateBB = F.begin();
-        StateE = F.end();
-        State = 1;
-
-      case 1:
-        // Find all 'return', 'resume', and 'unwind' instructions.
-        while (StateBB != StateE) {
-          BasicBlock *CurBB = StateBB++;
-
-          // Branches and invokes do not escape, only unwind, resume, and return
-          // do.
-          TerminatorInst *TI = CurBB->getTerminator();
-          if (!isa<ReturnInst>(TI) && !isa<ResumeInst>(TI))
-            continue;
-
-          Builder.SetInsertPoint(TI->getParent(), TI);
-          return &Builder;
-        }
-
-        State = 2;
-
-        // Find all 'call' instructions.
-        SmallVector<Instruction*,16> Calls;
-        for (Function::iterator BB = F.begin(),
-                                E = F.end(); BB != E; ++BB)
-          for (BasicBlock::iterator II = BB->begin(),
-                                    EE = BB->end(); II != EE; ++II)
-            if (CallInst *CI = dyn_cast<CallInst>(II))
-              if (!CI->getCalledFunction() ||
-                  !CI->getCalledFunction()->getIntrinsicID())
-                Calls.push_back(CI);
-
-        if (Calls.empty())
-          return nullptr;
-
-        // Create a cleanup block.
-        LLVMContext &C = F.getContext();
-        BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F);
-        Type *ExnTy = StructType::get(Type::getInt8PtrTy(C),
-                                      Type::getInt32Ty(C), nullptr);
-        Constant *PersFn =
-          F.getParent()->
-          getOrInsertFunction("__gcc_personality_v0",
-                              FunctionType::get(Type::getInt32Ty(C), true));
-        LandingPadInst *LPad = LandingPadInst::Create(ExnTy, PersFn, 1,
-                                                      "cleanup.lpad",
-                                                      CleanupBB);
-        LPad->setCleanup(true);
-        ResumeInst *RI = ResumeInst::Create(LPad, CleanupBB);
-
-        // Transform the 'call' instructions into 'invoke's branching to the
-        // cleanup block. Go in reverse order to make prettier BB names.
-        SmallVector<Value*,16> Args;
-        for (unsigned I = Calls.size(); I != 0; ) {
-          CallInst *CI = cast<CallInst>(Calls[--I]);
-
-          // Split the basic block containing the function call.
-          BasicBlock *CallBB = CI->getParent();
-          BasicBlock *NewBB =
+      // Create a cleanup block.
+      LLVMContext &C = F.getContext();
+      BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F);
+      Type *ExnTy =
+          StructType::get(Type::getInt8PtrTy(C), Type::getInt32Ty(C), nullptr);
+      Constant *PersFn = F.getParent()->getOrInsertFunction(
+          "__gcc_personality_v0", FunctionType::get(Type::getInt32Ty(C), true));
+      LandingPadInst *LPad =
+          LandingPadInst::Create(ExnTy, PersFn, 1, "cleanup.lpad", CleanupBB);
+      LPad->setCleanup(true);
+      ResumeInst *RI = ResumeInst::Create(LPad, CleanupBB);
+
+      // Transform the 'call' instructions into 'invoke's branching to the
+      // cleanup block. Go in reverse order to make prettier BB names.
+      SmallVector<Value *, 16> Args;
+      for (unsigned I = Calls.size(); I != 0;) {
+        CallInst *CI = cast<CallInst>(Calls[--I]);
+
+        // Split the basic block containing the function call.
+        BasicBlock *CallBB = CI->getParent();
+        BasicBlock *NewBB =
             CallBB->splitBasicBlock(CI, CallBB->getName() + ".cont");
 
-          // Remove the unconditional branch inserted at the end of CallBB.
-          CallBB->getInstList().pop_back();
-          NewBB->getInstList().remove(CI);
-
-          // Create a new invoke instruction.
-          Args.clear();
-          CallSite CS(CI);
-          Args.append(CS.arg_begin(), CS.arg_end());
-
-          InvokeInst *II = InvokeInst::Create(CI->getCalledValue(),
-                                              NewBB, CleanupBB,
-                                              Args, CI->getName(), CallBB);
-          II->setCallingConv(CI->getCallingConv());
-          II->setAttributes(CI->getAttributes());
-          CI->replaceAllUsesWith(II);
-          delete CI;
-        }
-
-        Builder.SetInsertPoint(RI->getParent(), RI);
-        return &Builder;
+        // Remove the unconditional branch inserted at the end of CallBB.
+        CallBB->getInstList().pop_back();
+        NewBB->getInstList().remove(CI);
+
+        // Create a new invoke instruction.
+        Args.clear();
+        CallSite CS(CI);
+        Args.append(CS.arg_begin(), CS.arg_end());
+
+        InvokeInst *II =
+            InvokeInst::Create(CI->getCalledValue(), NewBB, CleanupBB, Args,
+                               CI->getName(), CallBB);
+        II->setCallingConv(CI->getCallingConv());
+        II->setAttributes(CI->getAttributes());
+        CI->replaceAllUsesWith(II);
+        delete CI;
       }
+
+      Builder.SetInsertPoint(RI->getParent(), RI);
+      return &Builder;
     }
-  };
+  }
+};
 }
 
 // -----------------------------------------------------------------------------
 
-void llvm::linkShadowStackGC() { }
+void llvm::linkShadowStackGC() {}
 
 ShadowStackGC::ShadowStackGC() : Head(nullptr), StackEntryTy(nullptr) {
   InitRoots = true;
@@ -206,7 +201,7 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) {
 
   // Truncate the ShadowStackDescriptor if some metadata is null.
   unsigned NumMeta = 0;
-  SmallVector<Constant*, 16> Metadata;
+  SmallVector<Constant *, 16> Metadata;
   for (unsigned I = 0; I != Roots.size(); ++I) {
     Constant *C = cast<Constant>(Roots[I].first->getArgOperand(1));
     if (!C->isNullValue())
@@ -216,20 +211,19 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) {
   Metadata.resize(NumMeta);
 
   Type *Int32Ty = Type::getInt32Ty(F.getContext());
-  
+
   Constant *BaseElts[] = {
-    ConstantInt::get(Int32Ty, Roots.size(), false),
-    ConstantInt::get(Int32Ty, NumMeta, false),
+      ConstantInt::get(Int32Ty, Roots.size(), false),
+      ConstantInt::get(Int32Ty, NumMeta, false),
   };
 
   Constant *DescriptorElts[] = {
-    ConstantStruct::get(FrameMapTy, BaseElts),
-    ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), Metadata)
-  };
+      ConstantStruct::get(FrameMapTy, BaseElts),
+      ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), Metadata)};
+
+  Type *EltTys[] = {DescriptorElts[0]->getType(), DescriptorElts[1]->getType()};
+  StructType *STy = StructType::create(EltTys, "gc_map." + utostr(NumMeta));
 
-  Type *EltTys[] = { DescriptorElts[0]->getType(),DescriptorElts[1]->getType()};
-  StructType *STy = StructType::create(EltTys, "gc_map."+utostr(NumMeta));
-  
   Constant *FrameMap = ConstantStruct::get(STy, DescriptorElts);
 
   // FIXME: Is this actually dangerous as WritingAnLLVMPass.html claims? Seems
@@ -246,24 +240,23 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) {
   //        (which uses a FunctionPassManager (which segfaults (not asserts) if
   //        provided a ModulePass))).
   Constant *GV = new GlobalVariable(*F.getParent(), FrameMap->getType(), true,
-                                    GlobalVariable::InternalLinkage,
-                                    FrameMap, "__gc_" + F.getName());
+                                    GlobalVariable::InternalLinkage, FrameMap,
+                                    "__gc_" + F.getName());
 
   Constant *GEPIndices[2] = {
-                          ConstantInt::get(Type::getInt32Ty(F.getContext()), 0),
-                          ConstantInt::get(Type::getInt32Ty(F.getContext()), 0)
-                          };
+      ConstantInt::get(Type::getInt32Ty(F.getContext()), 0),
+      ConstantInt::get(Type::getInt32Ty(F.getContext()), 0)};
   return ConstantExpr::getGetElementPtr(GV, GEPIndices);
 }
 
-TypeShadowStackGC::GetConcreteStackEntryType(Function &F) {
+Type *ShadowStackGC::GetConcreteStackEntryType(Function &F) {
   // doInitialization creates the generic version of this type.
-  std::vector<Type*> EltTys;
+  std::vector<Type *> EltTys;
   EltTys.push_back(StackEntryTy);
   for (size_t I = 0; I != Roots.size(); I++)
     EltTys.push_back(Roots[I].second->getAllocatedType());
-  
-  return StructType::create(EltTys, "gc_stackentry."+F.getName().str());
+
+  return StructType::create(EltTys, "gc_stackentry." + F.getName().str());
 }
 
 /// doInitialization - If this module uses the GC intrinsics, find them now. If
@@ -274,10 +267,10 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) {
   //   int32_t NumMeta;  // Number of metadata descriptors. May be < NumRoots.
   //   void *Meta[];     // May be absent for roots without metadata.
   // };
-  std::vector<Type*> EltTys;
+  std::vector<Type *> EltTys;
   // 32 bits is ok up to a 32GB stack frame. :)
   EltTys.push_back(Type::getInt32Ty(M.getContext()));
-  // Specifies length of variable length array. 
+  // Specifies length of variable length array.
   EltTys.push_back(Type::getInt32Ty(M.getContext()));
   FrameMapTy = StructType::create(EltTys, "gc_map");
   PointerType *FrameMapPtrTy = PointerType::getUnqual(FrameMapTy);
@@ -287,9 +280,9 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) {
   //   FrameMap *Map;          // Pointer to constant FrameMap.
   //   void *Roots[];          // Stack roots (in-place array, so we pretend).
   // };
-  
+
   StackEntryTy = StructType::create(M.getContext(), "gc_stackentry");
-  
+
   EltTys.clear();
   EltTys.push_back(PointerType::getUnqual(StackEntryTy));
   EltTys.push_back(FrameMapPtrTy);
@@ -301,10 +294,9 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) {
   if (!Head) {
     // If the root chain does not exist, insert a new one with linkonce
     // linkage!
-    Head = new GlobalVariable(M, StackEntryPtrTy, false,
-                              GlobalValue::LinkOnceAnyLinkage,
-                              Constant::getNullValue(StackEntryPtrTy),
-                              "llvm_gc_root_chain");
+    Head = new GlobalVariable(
+        M, StackEntryPtrTy, false, GlobalValue::LinkOnceAnyLinkage,
+        Constant::getNullValue(StackEntryPtrTy), "llvm_gc_root_chain");
   } else if (Head->hasExternalLinkage() && Head->isDeclaration()) {
     Head->setInitializer(Constant::getNullValue(StackEntryPtrTy));
     Head->setLinkage(GlobalValue::LinkOnceAnyLinkage);
@@ -326,15 +318,16 @@ void ShadowStackGC::CollectRoots(Function &F) {
 
   assert(Roots.empty() && "Not cleaned up?");
 
-  SmallVector<std::pair<CallInst*, AllocaInst*>, 16> MetaRoots;
+  SmallVector<std::pair<CallInst *, AllocaInst *>, 16> MetaRoots;
 
   for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
     for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;)
       if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++))
         if (Function *F = CI->getCalledFunction())
           if (F->getIntrinsicID() == Intrinsic::gcroot) {
-            std::pair<CallInst*, AllocaInst*> Pair = std::make_pair(
-              CI, cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts()));
+            std::pair<CallInst *, AllocaInst *> Pair = std::make_pair(
+                CI,
+                cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts()));
             if (IsNullValue(CI->getArgOperand(1)))
               Roots.push_back(Pair);
             else
@@ -346,24 +339,25 @@ void ShadowStackGC::CollectRoots(Function &F) {
   Roots.insert(Roots.begin(), MetaRoots.begin(), MetaRoots.end());
 }
 
-GetElementPtrInst *
-ShadowStackGC::CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr,
-                         int Idx, int Idx2, const char *Name) {
-  Value *Indices[] = { ConstantInt::get(Type::getInt32Ty(Context), 0),
-                       ConstantInt::get(Type::getInt32Ty(Context), Idx),
-                       ConstantInt::get(Type::getInt32Ty(Context), Idx2) };
-  Value* Val = B.CreateGEP(BasePtr, Indices, Name);
+GetElementPtrInst *ShadowStackGC::CreateGEP(LLVMContext &Context,
+                                            IRBuilder<> &B, Value *BasePtr,
+                                            int Idx, int Idx2,
+                                            const char *Name) {
+  Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0),
+                      ConstantInt::get(Type::getInt32Ty(Context), Idx),
+                      ConstantInt::get(Type::getInt32Ty(Context), Idx2)};
+  Value *Val = B.CreateGEP(BasePtr, Indices, Name);
 
   assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant");
 
   return dyn_cast<GetElementPtrInst>(Val);
 }
 
-GetElementPtrInst *
-ShadowStackGC::CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr,
-                         int Idx, const char *Name) {
-  Value *Indices[] = { ConstantInt::get(Type::getInt32Ty(Context), 0),
-                       ConstantInt::get(Type::getInt32Ty(Context), Idx) };
+GetElementPtrInst *ShadowStackGC::CreateGEP(LLVMContext &Context,
+                                            IRBuilder<> &B, Value *BasePtr,
+                                            int Idx, const char *Name) {
+  Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0),
+                      ConstantInt::get(Type::getInt32Ty(Context), Idx)};
   Value *Val = B.CreateGEP(BasePtr, Indices, Name);
 
   assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant");
@@ -374,7 +368,7 @@ ShadowStackGC::CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr,
 /// runOnFunction - Insert code to maintain the shadow stack.
 bool ShadowStackGC::performCustomLowering(Function &F) {
   LLVMContext &Context = F.getContext();
-  
+
   // Find calls to llvm.gcroot.
   CollectRoots(F);
 
@@ -391,16 +385,17 @@ bool ShadowStackGC::performCustomLowering(Function &F) {
   BasicBlock::iterator IP = F.getEntryBlock().begin();
   IRBuilder<> AtEntry(IP->getParent(), IP);
 
-  Instruction *StackEntry = AtEntry.CreateAlloca(ConcreteStackEntryTy, nullptr,
-                                                 "gc_frame");
+  Instruction *StackEntry =
+      AtEntry.CreateAlloca(ConcreteStackEntryTy, nullptr, "gc_frame");
 
-  while (isa<AllocaInst>(IP)) ++IP;
+  while (isa<AllocaInst>(IP))
+    ++IP;
   AtEntry.SetInsertPoint(IP->getParent(), IP);
 
   // Initialize the map pointer and load the current head of the shadow stack.
-  Instruction *CurrentHead  = AtEntry.CreateLoad(Head, "gc_currhead");
-  Instruction *EntryMapPtr  = CreateGEP(Context, AtEntry, StackEntry,
-                                        0,1,"gc_frame.map");
+  Instruction *CurrentHead = AtEntry.CreateLoad(Head, "gc_currhead");
+  Instruction *EntryMapPtr =
+      CreateGEP(Context, AtEntry, StackEntry, 0, 1, "gc_frame.map");
   AtEntry.CreateStore(FrameMap, EntryMapPtr);
 
   // After all the allocas...
@@ -418,14 +413,15 @@ bool ShadowStackGC::performCustomLowering(Function &F) {
   // really necessary (the collector would never see the intermediate state at
   // runtime), but it's nicer not to push the half-initialized entry onto the
   // shadow stack.
-  while (isa<StoreInst>(IP)) ++IP;
+  while (isa<StoreInst>(IP))
+    ++IP;
   AtEntry.SetInsertPoint(IP->getParent(), IP);
 
   // Push the entry onto the shadow stack.
-  Instruction *EntryNextPtr = CreateGEP(Context, AtEntry,
-                                        StackEntry,0,0,"gc_frame.next");
-  Instruction *NewHeadVal   = CreateGEP(Context, AtEntry, 
-                                        StackEntry, 0, "gc_newhead");
+  Instruction *EntryNextPtr =
+      CreateGEP(Context, AtEntry, StackEntry, 0, 0, "gc_frame.next");
+  Instruction *NewHeadVal =
+      CreateGEP(Context, AtEntry, StackEntry, 0, "gc_newhead");
   AtEntry.CreateStore(CurrentHead, EntryNextPtr);
   AtEntry.CreateStore(NewHeadVal, Head);
 
@@ -434,10 +430,10 @@ bool ShadowStackGC::performCustomLowering(Function &F) {
   while (IRBuilder<> *AtExit = EE.Next()) {
     // Pop the entry from the shadow stack. Don't reuse CurrentHead from
     // AtEntry, since that would make the value live for the entire function.
-    Instruction *EntryNextPtr2 = CreateGEP(Context, *AtExit, StackEntry, 0, 0,
-                                           "gc_frame.next");
+    Instruction *EntryNextPtr2 =
+        CreateGEP(Context, *AtExit, StackEntry, 0, 0, "gc_frame.next");
     Value *SavedHead = AtExit->CreateLoad(EntryNextPtr2, "gc_savedhead");
-                       AtExit->CreateStore(SavedHead, Head);
+    AtExit->CreateStore(SavedHead, Head);
   }
 
   // Delete the original allocas (which are no longer used) and the intrinsic
index e20b270f42d54f3afeeae36404adba5c78ad8850..ed6d0e927f05c754df173e7c1d1c7622fcb3a6e2 100644 (file)
@@ -12,7 +12,7 @@
 // suitable as a default implementation usable with any collector which can
 // consume the standard stackmap format generated by statepoints, uses the
 // default addrespace to distinguish between gc managed and non-gc managed
-// pointers, and has reasonable relocation semantics.  
+// pointers, and has reasonable relocation semantics.
 //
 //===----------------------------------------------------------------------===//
 
@@ -45,8 +45,8 @@ public:
 };
 }
 
-static GCRegistry::Add<StatepointGC>
-X("statepoint-example", "an example strategy for statepoint");
+static GCRegistry::Add<StatepointGC> X("statepoint-example",
+                                       "an example strategy for statepoint");
 
 namespace llvm {
 void linkStatepointExampleGC() {}
index 18723a0f514da589e08c57772b6c0d033f00cab6..56e6946daf69b91da006408f2547811b76ead93a 100644 (file)
@@ -18,5 +18,5 @@ using namespace llvm;
 
 GCStrategy::GCStrategy()
     : UseStatepoints(false), NeededSafePoints(0), CustomReadBarriers(false),
-      CustomWriteBarriers(false), CustomRoots(false),
-      InitRoots(true), UsesMetadata(false) {}
+      CustomWriteBarriers(false), CustomRoots(false), InitRoots(true),
+      UsesMetadata(false) {}