2017-09-08 07:28:24 +08:00
|
|
|
//===- Bitcode/Writer/ValueEnumerator.h - Number values ---------*- C++ -*-===//
|
2007-04-22 14:24:45 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2007-04-22 14:24:45 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This class gives values and types Unique ID's.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-14 00:26:38 +08:00
|
|
|
#ifndef LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H
|
|
|
|
#define LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
2007-04-22 14:24:45 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2014-06-28 02:19:56 +08:00
|
|
|
#include "llvm/ADT/UniqueVector.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Attributes.h"
|
2017-11-04 04:24:19 +08:00
|
|
|
#include "llvm/IR/Metadata.h"
|
|
|
|
#include "llvm/IR/Type.h"
|
2014-07-29 05:19:41 +08:00
|
|
|
#include "llvm/IR/UseListOrder.h"
|
2017-09-08 07:28:24 +08:00
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <utility>
|
2007-04-22 14:24:45 +08:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
2007-04-26 12:42:16 +08:00
|
|
|
class BasicBlock;
|
2014-06-28 02:19:56 +08:00
|
|
|
class Comdat;
|
2007-04-22 14:24:45 +08:00
|
|
|
class Function;
|
2017-09-08 07:28:24 +08:00
|
|
|
class Instruction;
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-10 02:38:53 +08:00
|
|
|
class LocalAsMetadata;
|
2010-06-03 07:05:04 +08:00
|
|
|
class MDNode;
|
2017-09-08 07:28:24 +08:00
|
|
|
class Metadata;
|
|
|
|
class Module;
|
2010-01-09 08:30:14 +08:00
|
|
|
class NamedMDNode;
|
2011-12-08 04:44:46 +08:00
|
|
|
class raw_ostream;
|
2017-09-08 07:28:24 +08:00
|
|
|
class Type;
|
|
|
|
class Value;
|
|
|
|
class ValueSymbolTable;
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2013-09-12 02:05:11 +08:00
|
|
|
class ValueEnumerator {
|
2007-04-22 14:24:45 +08:00
|
|
|
public:
|
2017-09-08 07:28:24 +08:00
|
|
|
using TypeList = std::vector<Type *>;
|
2007-04-22 14:24:45 +08:00
|
|
|
|
|
|
|
// For each value, we remember its Value* and occurrence frequency.
|
2017-09-08 07:28:24 +08:00
|
|
|
using ValueList = std::vector<std::pair<const Value *, unsigned>>;
|
2014-07-29 05:19:41 +08:00
|
|
|
|
2017-04-25 04:38:30 +08:00
|
|
|
/// Attribute groups as encoded in bitcode are almost AttributeSets, but they
|
|
|
|
/// include the AttributeList index, so we have to track that in our map.
|
2017-09-08 07:28:24 +08:00
|
|
|
using IndexAndAttrSet = std::pair<unsigned, AttributeSet>;
|
2017-04-25 04:38:30 +08:00
|
|
|
|
2014-07-29 05:19:41 +08:00
|
|
|
UseListOrderStack UseListOrders;
|
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
private:
|
2017-09-08 07:28:24 +08:00
|
|
|
using TypeMapType = DenseMap<Type *, unsigned>;
|
2007-04-22 14:24:45 +08:00
|
|
|
TypeMapType TypeMap;
|
2007-04-24 08:16:04 +08:00
|
|
|
TypeList Types;
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
using ValueMapType = DenseMap<const Value *, unsigned>;
|
2007-04-22 14:24:45 +08:00
|
|
|
ValueMapType ValueMap;
|
2007-04-24 08:16:04 +08:00
|
|
|
ValueList Values;
|
2014-06-28 02:19:56 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
using ComdatSetType = UniqueVector<const Comdat *>;
|
2014-06-28 02:19:56 +08:00
|
|
|
ComdatSetType Comdats;
|
|
|
|
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-10 02:38:53 +08:00
|
|
|
std::vector<const Metadata *> MDs;
|
2016-04-02 23:22:57 +08:00
|
|
|
std::vector<const Metadata *> FunctionMDs;
|
|
|
|
|
|
|
|
/// Index of information about a piece of metadata.
|
|
|
|
struct MDIndex {
|
|
|
|
unsigned F = 0; ///< The ID of the function for this metadata, if any.
|
|
|
|
unsigned ID = 0; ///< The implicit ID of this metadata in bitcode.
|
|
|
|
|
|
|
|
MDIndex() = default;
|
|
|
|
explicit MDIndex(unsigned F) : F(F) {}
|
|
|
|
|
|
|
|
/// Check if this has a function tag, and it's different from NewF.
|
|
|
|
bool hasDifferentFunction(unsigned NewF) const { return F && F != NewF; }
|
|
|
|
|
|
|
|
/// Fetch the MD this references out of the given metadata array.
|
|
|
|
const Metadata *get(ArrayRef<const Metadata *> MDs) const {
|
|
|
|
assert(ID && "Expected non-zero ID");
|
|
|
|
assert(ID <= MDs.size() && "Expected valid ID");
|
|
|
|
return MDs[ID - 1];
|
|
|
|
}
|
|
|
|
};
|
2016-04-19 11:46:51 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
using MetadataMapType = DenseMap<const Metadata *, MDIndex>;
|
2015-12-30 07:00:22 +08:00
|
|
|
MetadataMapType MetadataMap;
|
2016-04-02 23:22:57 +08:00
|
|
|
|
|
|
|
/// Range of metadata IDs, as a half-open range.
|
|
|
|
struct MDRange {
|
|
|
|
unsigned First = 0;
|
|
|
|
unsigned Last = 0;
|
|
|
|
|
|
|
|
/// Number of strings in the prefix of the metadata range.
|
|
|
|
unsigned NumStrings = 0;
|
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
MDRange() = default;
|
2016-04-02 23:22:57 +08:00
|
|
|
explicit MDRange(unsigned First) : First(First) {}
|
|
|
|
};
|
|
|
|
SmallDenseMap<unsigned, MDRange, 1> FunctionMDInfo;
|
|
|
|
|
2015-04-15 07:45:11 +08:00
|
|
|
bool ShouldPreserveUseListOrder;
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
using AttributeGroupMapType = DenseMap<IndexAndAttrSet, unsigned>;
|
2013-02-12 06:33:26 +08:00
|
|
|
AttributeGroupMapType AttributeGroupMap;
|
2017-04-25 04:38:30 +08:00
|
|
|
std::vector<IndexAndAttrSet> AttributeGroups;
|
2013-02-11 07:06:02 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
using AttributeListMapType = DenseMap<AttributeList, unsigned>;
|
2017-04-25 04:38:30 +08:00
|
|
|
AttributeListMapType AttributeListMap;
|
|
|
|
std::vector<AttributeList> AttributeLists;
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2009-10-28 13:24:40 +08:00
|
|
|
/// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
|
|
|
|
/// the "getGlobalBasicBlockID" method.
|
|
|
|
mutable DenseMap<const BasicBlock*, unsigned> GlobalBasicBlockIDs;
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
using InstructionMapType = DenseMap<const Instruction *, unsigned>;
|
2009-09-19 03:26:43 +08:00
|
|
|
InstructionMapType InstructionMap;
|
|
|
|
unsigned InstructionCount;
|
|
|
|
|
2007-04-26 12:42:16 +08:00
|
|
|
/// BasicBlocks - This contains all the basic blocks for the currently
|
|
|
|
/// incorporated function. Their reverse mapping is stored in ValueMap.
|
|
|
|
std::vector<const BasicBlock*> BasicBlocks;
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2007-04-26 11:50:57 +08:00
|
|
|
/// When a function is incorporated, this is the size of the Values list
|
|
|
|
/// before incorporation.
|
2007-04-26 13:53:54 +08:00
|
|
|
unsigned NumModuleValues;
|
2010-08-24 10:24:03 +08:00
|
|
|
|
2015-12-30 07:00:22 +08:00
|
|
|
/// When a function is incorporated, this is the size of the Metadatas list
|
2010-08-24 10:24:03 +08:00
|
|
|
/// before incorporation.
|
2016-04-02 23:09:42 +08:00
|
|
|
unsigned NumModuleMDs = 0;
|
|
|
|
unsigned NumMDStrings = 0;
|
2010-08-24 10:24:03 +08:00
|
|
|
|
2007-04-26 13:53:54 +08:00
|
|
|
unsigned FirstFuncConstantID;
|
|
|
|
unsigned FirstInstID;
|
2012-09-16 01:09:36 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
public:
|
2015-04-15 07:45:11 +08:00
|
|
|
ValueEnumerator(const Module &M, bool ShouldPreserveUseListOrder);
|
2017-09-08 07:28:24 +08:00
|
|
|
ValueEnumerator(const ValueEnumerator &) = delete;
|
|
|
|
ValueEnumerator &operator=(const ValueEnumerator &) = delete;
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2011-12-08 04:44:46 +08:00
|
|
|
void dump() const;
|
|
|
|
void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-10 02:38:53 +08:00
|
|
|
void print(raw_ostream &OS, const MetadataMapType &Map,
|
|
|
|
const char *Name) const;
|
2011-12-08 04:44:46 +08:00
|
|
|
|
2009-08-04 14:00:18 +08:00
|
|
|
unsigned getValueID(const Value *V) const;
|
2017-09-08 07:28:24 +08:00
|
|
|
|
2015-01-20 09:00:23 +08:00
|
|
|
unsigned getMetadataID(const Metadata *MD) const {
|
|
|
|
auto ID = getMetadataOrNullID(MD);
|
|
|
|
assert(ID != 0 && "Metadata not in slotcalculator!");
|
|
|
|
return ID - 1;
|
|
|
|
}
|
2017-09-08 07:28:24 +08:00
|
|
|
|
2015-01-20 09:00:23 +08:00
|
|
|
unsigned getMetadataOrNullID(const Metadata *MD) const {
|
2016-04-02 23:22:57 +08:00
|
|
|
return MetadataMap.lookup(MD).ID;
|
2015-01-20 09:00:23 +08:00
|
|
|
}
|
2017-09-08 07:28:24 +08:00
|
|
|
|
2015-11-20 22:51:27 +08:00
|
|
|
unsigned numMDs() const { return MDs.size(); }
|
2009-08-04 14:00:18 +08:00
|
|
|
|
2015-04-15 07:45:11 +08:00
|
|
|
bool shouldPreserveUseListOrder() const { return ShouldPreserveUseListOrder; }
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
unsigned getTypeID(Type *T) const {
|
2007-04-22 14:24:45 +08:00
|
|
|
TypeMapType::const_iterator I = TypeMap.find(T);
|
|
|
|
assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
|
|
|
|
return I->second-1;
|
|
|
|
}
|
2009-09-19 03:26:43 +08:00
|
|
|
|
|
|
|
unsigned getInstructionID(const Instruction *I) const;
|
|
|
|
void setInstructionID(const Instruction *I);
|
|
|
|
|
2017-04-25 04:38:30 +08:00
|
|
|
unsigned getAttributeListID(AttributeList PAL) const {
|
2008-03-13 01:45:29 +08:00
|
|
|
if (PAL.isEmpty()) return 0; // Null maps to zero.
|
2017-04-25 04:38:30 +08:00
|
|
|
AttributeListMapType::const_iterator I = AttributeListMap.find(PAL);
|
|
|
|
assert(I != AttributeListMap.end() && "Attribute not in ValueEnumerator!");
|
2007-05-04 06:46:43 +08:00
|
|
|
return I->second;
|
|
|
|
}
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2017-04-25 04:38:30 +08:00
|
|
|
unsigned getAttributeGroupID(IndexAndAttrSet Group) const {
|
|
|
|
if (!Group.second.hasAttributes())
|
|
|
|
return 0; // Null maps to zero.
|
|
|
|
AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(Group);
|
2013-02-12 06:33:26 +08:00
|
|
|
assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
|
2013-02-11 07:06:02 +08:00
|
|
|
return I->second;
|
|
|
|
}
|
|
|
|
|
2007-04-26 13:53:54 +08:00
|
|
|
/// getFunctionConstantRange - Return the range of values that corresponds to
|
|
|
|
/// function-local constants.
|
|
|
|
void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
|
|
|
|
Start = FirstFuncConstantID;
|
|
|
|
End = FirstInstID;
|
|
|
|
}
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2007-04-24 08:16:04 +08:00
|
|
|
const ValueList &getValues() const { return Values; }
|
2016-04-02 23:09:42 +08:00
|
|
|
|
|
|
|
/// Check whether the current block has any metadata to emit.
|
|
|
|
bool hasMDs() const { return NumModuleMDs < MDs.size(); }
|
|
|
|
|
2016-04-02 23:16:56 +08:00
|
|
|
/// Get the MDString metadata for this block.
|
Reapply ~"Bitcode: Collect all MDString records into a single blob"
Spiritually reapply commit r264409 (reverted in r264410), albeit with a
bit of a redesign.
Firstly, avoid splitting the big blob into multiple chunks of strings.
r264409 imposed an arbitrary limit to avoid a massive allocation on the
shared 'Record' SmallVector. The bug with that commit only reproduced
when there were more than "chunk-size" strings. A test for this would
have been useless long-term, since we're liable to adjust the chunk-size
in the future.
Thus, eliminate the motivation for chunk-ing by storing the string sizes
in the blob. Here's the layout:
vbr6: # of strings
vbr6: offset-to-blob
blob:
[vbr6]: string lengths
[char]: concatenated strings
Secondly, make the output of llvm-bcanalyzer readable.
I noticed when debugging r264409 that llvm-bcanalyzer was outputting a
massive blob all in one line. Past a small number, the strings were
impossible to split in my head, and the lines were way too long. This
version adds support in llvm-bcanalyzer for pretty-printing.
<STRINGS abbrevid=4 op0=3 op1=9/> num-strings = 3 {
'abc'
'def'
'ghi'
}
From the original commit:
Inspired by Mehdi's similar patch, http://reviews.llvm.org/D18342, this
should (a) slightly reduce bitcode size, since there is less record
overhead, and (b) greatly improve reading speed, since blobs are super
cheap to deserialize.
llvm-svn: 264551
2016-03-28 07:17:54 +08:00
|
|
|
ArrayRef<const Metadata *> getMDStrings() const {
|
2016-04-02 23:09:42 +08:00
|
|
|
return makeArrayRef(MDs).slice(NumModuleMDs, NumMDStrings);
|
Reapply ~"Bitcode: Collect all MDString records into a single blob"
Spiritually reapply commit r264409 (reverted in r264410), albeit with a
bit of a redesign.
Firstly, avoid splitting the big blob into multiple chunks of strings.
r264409 imposed an arbitrary limit to avoid a massive allocation on the
shared 'Record' SmallVector. The bug with that commit only reproduced
when there were more than "chunk-size" strings. A test for this would
have been useless long-term, since we're liable to adjust the chunk-size
in the future.
Thus, eliminate the motivation for chunk-ing by storing the string sizes
in the blob. Here's the layout:
vbr6: # of strings
vbr6: offset-to-blob
blob:
[vbr6]: string lengths
[char]: concatenated strings
Secondly, make the output of llvm-bcanalyzer readable.
I noticed when debugging r264409 that llvm-bcanalyzer was outputting a
massive blob all in one line. Past a small number, the strings were
impossible to split in my head, and the lines were way too long. This
version adds support in llvm-bcanalyzer for pretty-printing.
<STRINGS abbrevid=4 op0=3 op1=9/> num-strings = 3 {
'abc'
'def'
'ghi'
}
From the original commit:
Inspired by Mehdi's similar patch, http://reviews.llvm.org/D18342, this
should (a) slightly reduce bitcode size, since there is less record
overhead, and (b) greatly improve reading speed, since blobs are super
cheap to deserialize.
llvm-svn: 264551
2016-03-28 07:17:54 +08:00
|
|
|
}
|
2016-04-02 23:09:42 +08:00
|
|
|
|
2016-04-02 23:16:56 +08:00
|
|
|
/// Get the non-MDString metadata for this block.
|
Reapply ~"Bitcode: Collect all MDString records into a single blob"
Spiritually reapply commit r264409 (reverted in r264410), albeit with a
bit of a redesign.
Firstly, avoid splitting the big blob into multiple chunks of strings.
r264409 imposed an arbitrary limit to avoid a massive allocation on the
shared 'Record' SmallVector. The bug with that commit only reproduced
when there were more than "chunk-size" strings. A test for this would
have been useless long-term, since we're liable to adjust the chunk-size
in the future.
Thus, eliminate the motivation for chunk-ing by storing the string sizes
in the blob. Here's the layout:
vbr6: # of strings
vbr6: offset-to-blob
blob:
[vbr6]: string lengths
[char]: concatenated strings
Secondly, make the output of llvm-bcanalyzer readable.
I noticed when debugging r264409 that llvm-bcanalyzer was outputting a
massive blob all in one line. Past a small number, the strings were
impossible to split in my head, and the lines were way too long. This
version adds support in llvm-bcanalyzer for pretty-printing.
<STRINGS abbrevid=4 op0=3 op1=9/> num-strings = 3 {
'abc'
'def'
'ghi'
}
From the original commit:
Inspired by Mehdi's similar patch, http://reviews.llvm.org/D18342, this
should (a) slightly reduce bitcode size, since there is less record
overhead, and (b) greatly improve reading speed, since blobs are super
cheap to deserialize.
llvm-svn: 264551
2016-03-28 07:17:54 +08:00
|
|
|
ArrayRef<const Metadata *> getNonMDStrings() const {
|
2016-04-02 23:09:42 +08:00
|
|
|
return makeArrayRef(MDs).slice(NumModuleMDs).slice(NumMDStrings);
|
2010-06-03 07:05:04 +08:00
|
|
|
}
|
Reapply ~"Bitcode: Collect all MDString records into a single blob"
Spiritually reapply commit r264409 (reverted in r264410), albeit with a
bit of a redesign.
Firstly, avoid splitting the big blob into multiple chunks of strings.
r264409 imposed an arbitrary limit to avoid a massive allocation on the
shared 'Record' SmallVector. The bug with that commit only reproduced
when there were more than "chunk-size" strings. A test for this would
have been useless long-term, since we're liable to adjust the chunk-size
in the future.
Thus, eliminate the motivation for chunk-ing by storing the string sizes
in the blob. Here's the layout:
vbr6: # of strings
vbr6: offset-to-blob
blob:
[vbr6]: string lengths
[char]: concatenated strings
Secondly, make the output of llvm-bcanalyzer readable.
I noticed when debugging r264409 that llvm-bcanalyzer was outputting a
massive blob all in one line. Past a small number, the strings were
impossible to split in my head, and the lines were way too long. This
version adds support in llvm-bcanalyzer for pretty-printing.
<STRINGS abbrevid=4 op0=3 op1=9/> num-strings = 3 {
'abc'
'def'
'ghi'
}
From the original commit:
Inspired by Mehdi's similar patch, http://reviews.llvm.org/D18342, this
should (a) slightly reduce bitcode size, since there is less record
overhead, and (b) greatly improve reading speed, since blobs are super
cheap to deserialize.
llvm-svn: 264551
2016-03-28 07:17:54 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
const TypeList &getTypes() const { return Types; }
|
2017-09-08 07:28:24 +08:00
|
|
|
|
2007-04-26 12:42:16 +08:00
|
|
|
const std::vector<const BasicBlock*> &getBasicBlocks() const {
|
2012-11-25 23:23:39 +08:00
|
|
|
return BasicBlocks;
|
2007-04-26 12:42:16 +08:00
|
|
|
}
|
2017-09-08 07:28:24 +08:00
|
|
|
|
2017-04-25 04:38:30 +08:00
|
|
|
const std::vector<AttributeList> &getAttributeLists() const { return AttributeLists; }
|
2017-09-08 07:28:24 +08:00
|
|
|
|
2017-04-25 04:38:30 +08:00
|
|
|
const std::vector<IndexAndAttrSet> &getAttributeGroups() const {
|
2013-02-12 06:33:26 +08:00
|
|
|
return AttributeGroups;
|
2013-02-11 07:06:02 +08:00
|
|
|
}
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2014-06-28 02:19:56 +08:00
|
|
|
const ComdatSetType &getComdats() const { return Comdats; }
|
|
|
|
unsigned getComdatID(const Comdat *C) const;
|
|
|
|
|
2009-10-28 13:24:40 +08:00
|
|
|
/// getGlobalBasicBlockID - This returns the function-specific ID for the
|
|
|
|
/// specified basic block. This is relatively expensive information, so it
|
|
|
|
/// should only be used by rare constructs such as address-of-label.
|
|
|
|
unsigned getGlobalBasicBlockID(const BasicBlock *BB) const;
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2011-06-04 01:02:19 +08:00
|
|
|
/// incorporateFunction/purgeFunction - If you'd like to deal with a function,
|
2007-04-22 14:24:45 +08:00
|
|
|
/// use these two methods to get its data into the ValueEnumerator!
|
2011-06-04 01:02:19 +08:00
|
|
|
void incorporateFunction(const Function &F);
|
2017-09-08 07:28:24 +08:00
|
|
|
|
2011-06-04 01:02:19 +08:00
|
|
|
void purgeFunction();
|
2015-02-25 08:51:52 +08:00
|
|
|
uint64_t computeBitsRequiredForTypeIndicies() const;
|
2007-04-22 14:24:45 +08:00
|
|
|
|
|
|
|
private:
|
2007-05-04 13:21:47 +08:00
|
|
|
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2016-04-02 23:22:57 +08:00
|
|
|
/// Reorder the reachable metadata.
|
|
|
|
///
|
|
|
|
/// This is not just an optimization, but is mandatory for emitting MDString
|
|
|
|
/// correctly.
|
Reapply ~"Bitcode: Collect all MDString records into a single blob"
Spiritually reapply commit r264409 (reverted in r264410), albeit with a
bit of a redesign.
Firstly, avoid splitting the big blob into multiple chunks of strings.
r264409 imposed an arbitrary limit to avoid a massive allocation on the
shared 'Record' SmallVector. The bug with that commit only reproduced
when there were more than "chunk-size" strings. A test for this would
have been useless long-term, since we're liable to adjust the chunk-size
in the future.
Thus, eliminate the motivation for chunk-ing by storing the string sizes
in the blob. Here's the layout:
vbr6: # of strings
vbr6: offset-to-blob
blob:
[vbr6]: string lengths
[char]: concatenated strings
Secondly, make the output of llvm-bcanalyzer readable.
I noticed when debugging r264409 that llvm-bcanalyzer was outputting a
massive blob all in one line. Past a small number, the strings were
impossible to split in my head, and the lines were way too long. This
version adds support in llvm-bcanalyzer for pretty-printing.
<STRINGS abbrevid=4 op0=3 op1=9/> num-strings = 3 {
'abc'
'def'
'ghi'
}
From the original commit:
Inspired by Mehdi's similar patch, http://reviews.llvm.org/D18342, this
should (a) slightly reduce bitcode size, since there is less record
overhead, and (b) greatly improve reading speed, since blobs are super
cheap to deserialize.
llvm-svn: 264551
2016-03-28 07:17:54 +08:00
|
|
|
void organizeMetadata();
|
|
|
|
|
2016-04-02 23:22:57 +08:00
|
|
|
/// Drop the function tag from the transitive operands of the given node.
|
2016-04-19 11:46:51 +08:00
|
|
|
void dropFunctionFromMetadata(MetadataMapType::value_type &FirstMD);
|
2016-04-02 23:22:57 +08:00
|
|
|
|
|
|
|
/// Incorporate the function metadata.
|
|
|
|
///
|
|
|
|
/// This should be called before enumerating LocalAsMetadata for the
|
|
|
|
/// function.
|
|
|
|
void incorporateFunctionMetadata(const Function &F);
|
|
|
|
|
ValueMapper/Enumerator: Clean up code in post-order traversals, NFC
Re-layer the functions in the new (i.e., newly correct) post-order
traversals in ValueEnumerator (r266947) and ValueMapper (r266949).
Instead of adding a node to the worklist in a helper function and
returning a flag to say what happened, return the node itself. This
makes the code way cleaner: the worklist is local to the main function,
there is no flag for an early loop exit (since we can cleanly bury the
loop), and it's perfectly clear when pointers into the worklist might be
invalidated.
I'm fixing both algorithms in the same commit to avoid repeating the
commit message; if you take the time to understand one the other should
be easy. The diff itself isn't entirely obvious since the traversals
have some noise (i.e., things to do), but here's the high-level change:
auto helper = [&WL](T *Op) { auto helper = [](T **&I, T **E) {
=> while (I != E) {
if (shouldVisit(Op)) { T *Op = *I++;
WL.push(Op, Op->begin()); if (shouldVisit(Op)) {
return true; return Op;
} }
return false; return nullptr;
}; };
=>
WL.push(S, S->begin()); WL.push(S, S->begin());
while (!empty()) { while (!empty()) {
auto *N = WL.top().N; auto *N = WL.top().N;
auto *&I = WL.top().I; auto *&I = WL.top().I;
bool DidChange = false;
while (I != N->end())
if (helper(*I++)) { => if (T *Op = helper(I, N->end()) {
DidChange = true; WL.push(Op, Op->begin());
break; continue;
} }
if (DidChange)
continue;
POT.push(WL.pop()); => POT.push(WL.pop());
} }
Thanks to Mehdi for helping me find a better way to layer this.
llvm-svn: 267099
2016-04-22 10:33:06 +08:00
|
|
|
/// Enumerate a single instance of metadata with the given function tag.
|
|
|
|
///
|
|
|
|
/// If \c MD has already been enumerated, check that \c F matches its
|
|
|
|
/// function tag. If not, call \a dropFunctionFromMetadata().
|
|
|
|
///
|
|
|
|
/// Otherwise, mark \c MD as visited. Assign it an ID, or just return it if
|
|
|
|
/// it's an \a MDNode.
|
|
|
|
const MDNode *enumerateMetadataImpl(unsigned F, const Metadata *MD);
|
2016-04-02 23:22:57 +08:00
|
|
|
|
2016-06-22 07:42:48 +08:00
|
|
|
unsigned getMetadataFunctionID(const Function *F) const;
|
BitcodeWriter: Emit uniqued subgraphs after all distinct nodes
Since forward references for uniqued node operands are expensive (and
those for distinct node operands are cheap due to
DistinctMDOperandPlaceholder), minimize forward references in uniqued
node operands.
Moreover, guarantee that when a cycle is broken by a distinct node, none
of the uniqued nodes have any forward references. In
ValueEnumerator::EnumerateMetadata, enumerate uniqued node subgraphs
first, delaying distinct nodes until all uniqued nodes have been
handled. This guarantees that uniqued nodes only have forward
references when there is a uniquing cycle (since r267276 changed
ValueEnumerator::organizeMetadata to partition distinct nodes in front
of uniqued nodes as a post-pass).
Note that a single uniqued subgraph can hit multiple distinct nodes at
its leaves. Ideally these would themselves be emitted in post-order,
but this commit doesn't attempt that; I think it requires an extra pass
through the edges, which I'm not convinced is worth it (since
DistinctMDOperandPlaceholder makes forward references quite cheap
between distinct nodes).
I've added two testcases:
- test/Bitcode/mdnodes-distinct-in-post-order.ll is just like
test/Bitcode/mdnodes-in-post-order.ll, except with distinct nodes
instead of uniqued ones. This confirms that, in the absence of
uniqued nodes, distinct nodes are still emitted in post-order.
- test/Bitcode/mdnodes-distinct-nodes-break-cycles.ll is the minimal
example where a naive post-order traversal would cause one uniqued
node to forward-reference another. IOW, it's the motivating test.
llvm-svn: 267278
2016-04-23 12:59:22 +08:00
|
|
|
|
|
|
|
/// Enumerate reachable metadata in (almost) post-order.
|
|
|
|
///
|
|
|
|
/// Enumerate all the metadata reachable from MD. We want to minimize the
|
|
|
|
/// cost of reading bitcode records, and so the primary consideration is that
|
|
|
|
/// operands of uniqued nodes are resolved before the nodes are read. This
|
|
|
|
/// avoids re-uniquing them on the context and factors away RAUW support.
|
|
|
|
///
|
|
|
|
/// This algorithm guarantees that subgraphs of uniqued nodes are in
|
|
|
|
/// post-order. Distinct subgraphs reachable only from a single uniqued node
|
|
|
|
/// will be in post-order.
|
|
|
|
///
|
|
|
|
/// \note The relative order of a distinct and uniqued node is irrelevant.
|
|
|
|
/// \a organizeMetadata() will later partition distinct nodes ahead of
|
|
|
|
/// uniqued ones.
|
|
|
|
///{
|
2016-06-22 07:42:48 +08:00
|
|
|
void EnumerateMetadata(const Function *F, const Metadata *MD);
|
2016-04-02 23:22:57 +08:00
|
|
|
void EnumerateMetadata(unsigned F, const Metadata *MD);
|
BitcodeWriter: Emit uniqued subgraphs after all distinct nodes
Since forward references for uniqued node operands are expensive (and
those for distinct node operands are cheap due to
DistinctMDOperandPlaceholder), minimize forward references in uniqued
node operands.
Moreover, guarantee that when a cycle is broken by a distinct node, none
of the uniqued nodes have any forward references. In
ValueEnumerator::EnumerateMetadata, enumerate uniqued node subgraphs
first, delaying distinct nodes until all uniqued nodes have been
handled. This guarantees that uniqued nodes only have forward
references when there is a uniquing cycle (since r267276 changed
ValueEnumerator::organizeMetadata to partition distinct nodes in front
of uniqued nodes as a post-pass).
Note that a single uniqued subgraph can hit multiple distinct nodes at
its leaves. Ideally these would themselves be emitted in post-order,
but this commit doesn't attempt that; I think it requires an extra pass
through the edges, which I'm not convinced is worth it (since
DistinctMDOperandPlaceholder makes forward references quite cheap
between distinct nodes).
I've added two testcases:
- test/Bitcode/mdnodes-distinct-in-post-order.ll is just like
test/Bitcode/mdnodes-in-post-order.ll, except with distinct nodes
instead of uniqued ones. This confirms that, in the absence of
uniqued nodes, distinct nodes are still emitted in post-order.
- test/Bitcode/mdnodes-distinct-nodes-break-cycles.ll is the minimal
example where a naive post-order traversal would cause one uniqued
node to forward-reference another. IOW, it's the motivating test.
llvm-svn: 267278
2016-04-23 12:59:22 +08:00
|
|
|
///}
|
|
|
|
|
2016-04-02 23:22:57 +08:00
|
|
|
void EnumerateFunctionLocalMetadata(const Function &F,
|
|
|
|
const LocalAsMetadata *Local);
|
|
|
|
void EnumerateFunctionLocalMetadata(unsigned F, const LocalAsMetadata *Local);
|
2010-01-09 08:30:14 +08:00
|
|
|
void EnumerateNamedMDNode(const NamedMDNode *NMD);
|
2010-01-15 03:54:11 +08:00
|
|
|
void EnumerateValue(const Value *V);
|
2011-07-18 12:54:35 +08:00
|
|
|
void EnumerateType(Type *T);
|
2010-01-15 03:54:11 +08:00
|
|
|
void EnumerateOperandType(const Value *V);
|
Rename AttributeSet to AttributeList
Summary:
This class is a list of AttributeSetNodes corresponding the function
prototype of a call or function declaration. This class used to be
called ParamAttrListPtr, then AttrListPtr, then AttributeSet. It is
typically accessed by parameter and return value index, so
"AttributeList" seems like a more intuitive name.
Rename AttributeSetImpl to AttributeListImpl to follow suit.
It's useful to rename this class so that we can rename AttributeSetNode
to AttributeSet later. AttributeSet is the set of attributes that apply
to a single function, argument, or return value.
Reviewers: sanjoy, javed.absar, chandlerc, pete
Reviewed By: pete
Subscribers: pete, jholewinski, arsenm, dschuff, mehdi_amini, jfb, nhaehnle, sbc100, void, llvm-commits
Differential Revision: https://reviews.llvm.org/D31102
llvm-svn: 298393
2017-03-22 00:57:19 +08:00
|
|
|
void EnumerateAttributes(AttributeList PAL);
|
2012-11-25 23:23:39 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
|
2014-11-18 04:06:27 +08:00
|
|
|
void EnumerateNamedMetadata(const Module &M);
|
2007-04-22 14:24:45 +08:00
|
|
|
};
|
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
} // end namespace llvm
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2017-09-08 07:28:24 +08:00
|
|
|
#endif // LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H
|