2007-04-29 13:31:57 +08:00
|
|
|
//===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===//
|
2007-04-22 14:24:45 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-04-22 14:24:45 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Bitcode writer implementation.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "ValueEnumerator.h"
|
2016-04-01 13:33:11 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2007-04-22 14:24:45 +08:00
|
|
|
#include "llvm/Bitcode/BitstreamWriter.h"
|
2007-04-23 09:01:37 +08:00
|
|
|
#include "llvm/Bitcode/LLVMBitCodes.h"
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
#include "llvm/Bitcode/ReaderWriter.h"
|
2015-09-25 07:34:52 +08:00
|
|
|
#include "llvm/IR/CallSite.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Constants.h"
|
2015-02-03 02:53:21 +08:00
|
|
|
#include "llvm/IR/DebugInfoMetadata.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
|
|
|
#include "llvm/IR/InlineAsm.h"
|
|
|
|
#include "llvm/IR/Instructions.h"
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
#include "llvm/IR/LLVMContext.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Module.h"
|
|
|
|
#include "llvm/IR/Operator.h"
|
2014-07-25 22:49:26 +08:00
|
|
|
#include "llvm/IR/UseListOrder.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/ValueSymbolTable.h"
|
2011-12-08 05:44:12 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2009-07-12 04:10:48 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2007-04-22 14:24:45 +08:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2010-11-30 02:16:10 +08:00
|
|
|
#include "llvm/Support/Program.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2016-04-01 13:33:11 +08:00
|
|
|
#include "llvm/Support/SHA1.h"
|
2010-12-20 04:43:38 +08:00
|
|
|
#include <cctype>
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
#include <map>
|
2007-04-22 14:24:45 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2007-05-05 04:52:02 +08:00
|
|
|
/// These are manifest constants used by the bitcode writer. They do not need to
|
|
|
|
/// be kept in sync with the reader, but need to be consistent within this file.
|
|
|
|
enum {
|
|
|
|
// VALUE_SYMTAB_BLOCK abbrev id's.
|
|
|
|
VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
|
2007-05-05 04:58:35 +08:00
|
|
|
VST_ENTRY_7_ABBREV,
|
2007-05-05 09:26:50 +08:00
|
|
|
VST_ENTRY_6_ABBREV,
|
2007-05-05 15:36:14 +08:00
|
|
|
VST_BBENTRY_6_ABBREV,
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:36:14 +08:00
|
|
|
// CONSTANTS_BLOCK abbrev id's.
|
|
|
|
CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
|
|
|
|
CONSTANTS_INTEGER_ABBREV,
|
|
|
|
CONSTANTS_CE_CAST_Abbrev,
|
2007-05-05 15:44:49 +08:00
|
|
|
CONSTANTS_NULL_Abbrev,
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:44:49 +08:00
|
|
|
// FUNCTION_BLOCK abbrev id's.
|
2007-05-06 09:28:01 +08:00
|
|
|
FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
|
2007-05-06 10:38:57 +08:00
|
|
|
FUNCTION_INST_BINOP_ABBREV,
|
2009-07-21 05:19:07 +08:00
|
|
|
FUNCTION_INST_BINOP_FLAGS_ABBREV,
|
2007-05-06 10:38:57 +08:00
|
|
|
FUNCTION_INST_CAST_ABBREV,
|
2007-05-06 09:28:01 +08:00
|
|
|
FUNCTION_INST_RET_VOID_ABBREV,
|
|
|
|
FUNCTION_INST_RET_VAL_ABBREV,
|
2015-02-25 09:08:52 +08:00
|
|
|
FUNCTION_INST_UNREACHABLE_ABBREV,
|
|
|
|
FUNCTION_INST_GEP_ABBREV,
|
2007-05-05 04:52:02 +08:00
|
|
|
};
|
|
|
|
|
2007-04-24 15:07:11 +08:00
|
|
|
static unsigned GetEncodedCastOpcode(unsigned Opcode) {
|
|
|
|
switch (Opcode) {
|
2009-07-15 00:55:14 +08:00
|
|
|
default: llvm_unreachable("Unknown cast instruction!");
|
2007-04-24 15:07:11 +08:00
|
|
|
case Instruction::Trunc : return bitc::CAST_TRUNC;
|
|
|
|
case Instruction::ZExt : return bitc::CAST_ZEXT;
|
|
|
|
case Instruction::SExt : return bitc::CAST_SEXT;
|
|
|
|
case Instruction::FPToUI : return bitc::CAST_FPTOUI;
|
|
|
|
case Instruction::FPToSI : return bitc::CAST_FPTOSI;
|
|
|
|
case Instruction::UIToFP : return bitc::CAST_UITOFP;
|
|
|
|
case Instruction::SIToFP : return bitc::CAST_SITOFP;
|
|
|
|
case Instruction::FPTrunc : return bitc::CAST_FPTRUNC;
|
|
|
|
case Instruction::FPExt : return bitc::CAST_FPEXT;
|
|
|
|
case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
|
|
|
|
case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
|
|
|
|
case Instruction::BitCast : return bitc::CAST_BITCAST;
|
2013-11-18 10:51:33 +08:00
|
|
|
case Instruction::AddrSpaceCast: return bitc::CAST_ADDRSPACECAST;
|
2007-04-24 15:07:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned GetEncodedBinaryOpcode(unsigned Opcode) {
|
|
|
|
switch (Opcode) {
|
2009-07-15 00:55:14 +08:00
|
|
|
default: llvm_unreachable("Unknown binary instruction!");
|
2009-06-05 06:49:04 +08:00
|
|
|
case Instruction::Add:
|
|
|
|
case Instruction::FAdd: return bitc::BINOP_ADD;
|
|
|
|
case Instruction::Sub:
|
|
|
|
case Instruction::FSub: return bitc::BINOP_SUB;
|
|
|
|
case Instruction::Mul:
|
|
|
|
case Instruction::FMul: return bitc::BINOP_MUL;
|
2007-04-24 15:07:11 +08:00
|
|
|
case Instruction::UDiv: return bitc::BINOP_UDIV;
|
|
|
|
case Instruction::FDiv:
|
|
|
|
case Instruction::SDiv: return bitc::BINOP_SDIV;
|
|
|
|
case Instruction::URem: return bitc::BINOP_UREM;
|
|
|
|
case Instruction::FRem:
|
|
|
|
case Instruction::SRem: return bitc::BINOP_SREM;
|
|
|
|
case Instruction::Shl: return bitc::BINOP_SHL;
|
|
|
|
case Instruction::LShr: return bitc::BINOP_LSHR;
|
|
|
|
case Instruction::AShr: return bitc::BINOP_ASHR;
|
|
|
|
case Instruction::And: return bitc::BINOP_AND;
|
|
|
|
case Instruction::Or: return bitc::BINOP_OR;
|
|
|
|
case Instruction::Xor: return bitc::BINOP_XOR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-29 05:48:00 +08:00
|
|
|
static unsigned GetEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
|
|
|
|
switch (Op) {
|
|
|
|
default: llvm_unreachable("Unknown RMW operation!");
|
|
|
|
case AtomicRMWInst::Xchg: return bitc::RMW_XCHG;
|
|
|
|
case AtomicRMWInst::Add: return bitc::RMW_ADD;
|
|
|
|
case AtomicRMWInst::Sub: return bitc::RMW_SUB;
|
|
|
|
case AtomicRMWInst::And: return bitc::RMW_AND;
|
|
|
|
case AtomicRMWInst::Nand: return bitc::RMW_NAND;
|
|
|
|
case AtomicRMWInst::Or: return bitc::RMW_OR;
|
|
|
|
case AtomicRMWInst::Xor: return bitc::RMW_XOR;
|
|
|
|
case AtomicRMWInst::Max: return bitc::RMW_MAX;
|
|
|
|
case AtomicRMWInst::Min: return bitc::RMW_MIN;
|
|
|
|
case AtomicRMWInst::UMax: return bitc::RMW_UMAX;
|
|
|
|
case AtomicRMWInst::UMin: return bitc::RMW_UMIN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-26 07:16:38 +08:00
|
|
|
static unsigned GetEncodedOrdering(AtomicOrdering Ordering) {
|
|
|
|
switch (Ordering) {
|
2016-04-07 05:19:33 +08:00
|
|
|
case AtomicOrdering::NotAtomic: return bitc::ORDERING_NOTATOMIC;
|
|
|
|
case AtomicOrdering::Unordered: return bitc::ORDERING_UNORDERED;
|
|
|
|
case AtomicOrdering::Monotonic: return bitc::ORDERING_MONOTONIC;
|
|
|
|
case AtomicOrdering::Acquire: return bitc::ORDERING_ACQUIRE;
|
|
|
|
case AtomicOrdering::Release: return bitc::ORDERING_RELEASE;
|
|
|
|
case AtomicOrdering::AcquireRelease: return bitc::ORDERING_ACQREL;
|
|
|
|
case AtomicOrdering::SequentiallyConsistent: return bitc::ORDERING_SEQCST;
|
2011-07-26 07:16:38 +08:00
|
|
|
}
|
2012-01-11 02:08:01 +08:00
|
|
|
llvm_unreachable("Invalid ordering");
|
2011-07-26 07:16:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) {
|
|
|
|
switch (SynchScope) {
|
|
|
|
case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD;
|
|
|
|
case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD;
|
|
|
|
}
|
2012-01-11 02:08:01 +08:00
|
|
|
llvm_unreachable("Invalid synch scope");
|
2011-07-26 07:16:38 +08:00
|
|
|
}
|
|
|
|
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
static void WriteStringRecord(unsigned Code, StringRef Str,
|
2007-04-22 14:24:45 +08:00
|
|
|
unsigned AbbrevToUse, BitstreamWriter &Stream) {
|
|
|
|
SmallVector<unsigned, 64> Vals;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 03:11:41 +08:00
|
|
|
// Code: [strchar x N]
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
for (unsigned i = 0, e = Str.size(); i != e; ++i) {
|
|
|
|
if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i]))
|
|
|
|
AbbrevToUse = 0;
|
2007-04-22 14:24:45 +08:00
|
|
|
Vals.push_back(Str[i]);
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
// Emit the finished record.
|
|
|
|
Stream.EmitRecord(Code, Vals, AbbrevToUse);
|
|
|
|
}
|
|
|
|
|
2013-07-26 12:16:55 +08:00
|
|
|
static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
|
|
|
|
switch (Kind) {
|
|
|
|
case Attribute::Alignment:
|
|
|
|
return bitc::ATTR_KIND_ALIGNMENT;
|
2016-04-12 09:05:35 +08:00
|
|
|
case Attribute::AllocSize:
|
|
|
|
return bitc::ATTR_KIND_ALLOC_SIZE;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::AlwaysInline:
|
|
|
|
return bitc::ATTR_KIND_ALWAYS_INLINE;
|
2015-07-11 18:30:36 +08:00
|
|
|
case Attribute::ArgMemOnly:
|
|
|
|
return bitc::ATTR_KIND_ARGMEMONLY;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::Builtin:
|
|
|
|
return bitc::ATTR_KIND_BUILTIN;
|
|
|
|
case Attribute::ByVal:
|
|
|
|
return bitc::ATTR_KIND_BY_VAL;
|
2015-05-27 07:48:40 +08:00
|
|
|
case Attribute::Convergent:
|
|
|
|
return bitc::ATTR_KIND_CONVERGENT;
|
2013-12-19 10:14:12 +08:00
|
|
|
case Attribute::InAlloca:
|
|
|
|
return bitc::ATTR_KIND_IN_ALLOCA;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::Cold:
|
|
|
|
return bitc::ATTR_KIND_COLD;
|
2015-12-17 00:16:19 +08:00
|
|
|
case Attribute::InaccessibleMemOnly:
|
|
|
|
return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY;
|
|
|
|
case Attribute::InaccessibleMemOrArgMemOnly:
|
|
|
|
return bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::InlineHint:
|
|
|
|
return bitc::ATTR_KIND_INLINE_HINT;
|
|
|
|
case Attribute::InReg:
|
|
|
|
return bitc::ATTR_KIND_IN_REG;
|
2014-06-06 03:29:43 +08:00
|
|
|
case Attribute::JumpTable:
|
|
|
|
return bitc::ATTR_KIND_JUMP_TABLE;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::MinSize:
|
|
|
|
return bitc::ATTR_KIND_MIN_SIZE;
|
|
|
|
case Attribute::Naked:
|
|
|
|
return bitc::ATTR_KIND_NAKED;
|
|
|
|
case Attribute::Nest:
|
|
|
|
return bitc::ATTR_KIND_NEST;
|
|
|
|
case Attribute::NoAlias:
|
|
|
|
return bitc::ATTR_KIND_NO_ALIAS;
|
|
|
|
case Attribute::NoBuiltin:
|
|
|
|
return bitc::ATTR_KIND_NO_BUILTIN;
|
|
|
|
case Attribute::NoCapture:
|
|
|
|
return bitc::ATTR_KIND_NO_CAPTURE;
|
|
|
|
case Attribute::NoDuplicate:
|
|
|
|
return bitc::ATTR_KIND_NO_DUPLICATE;
|
|
|
|
case Attribute::NoImplicitFloat:
|
|
|
|
return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;
|
|
|
|
case Attribute::NoInline:
|
|
|
|
return bitc::ATTR_KIND_NO_INLINE;
|
2015-11-06 18:32:53 +08:00
|
|
|
case Attribute::NoRecurse:
|
|
|
|
return bitc::ATTR_KIND_NO_RECURSE;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::NonLazyBind:
|
|
|
|
return bitc::ATTR_KIND_NON_LAZY_BIND;
|
2014-05-20 09:23:40 +08:00
|
|
|
case Attribute::NonNull:
|
|
|
|
return bitc::ATTR_KIND_NON_NULL;
|
2014-07-18 23:51:28 +08:00
|
|
|
case Attribute::Dereferenceable:
|
|
|
|
return bitc::ATTR_KIND_DEREFERENCEABLE;
|
2015-04-17 04:29:50 +08:00
|
|
|
case Attribute::DereferenceableOrNull:
|
|
|
|
return bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::NoRedZone:
|
|
|
|
return bitc::ATTR_KIND_NO_RED_ZONE;
|
|
|
|
case Attribute::NoReturn:
|
|
|
|
return bitc::ATTR_KIND_NO_RETURN;
|
|
|
|
case Attribute::NoUnwind:
|
|
|
|
return bitc::ATTR_KIND_NO_UNWIND;
|
|
|
|
case Attribute::OptimizeForSize:
|
|
|
|
return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;
|
2013-08-23 19:53:55 +08:00
|
|
|
case Attribute::OptimizeNone:
|
|
|
|
return bitc::ATTR_KIND_OPTIMIZE_NONE;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::ReadNone:
|
|
|
|
return bitc::ATTR_KIND_READ_NONE;
|
|
|
|
case Attribute::ReadOnly:
|
|
|
|
return bitc::ATTR_KIND_READ_ONLY;
|
|
|
|
case Attribute::Returned:
|
|
|
|
return bitc::ATTR_KIND_RETURNED;
|
|
|
|
case Attribute::ReturnsTwice:
|
|
|
|
return bitc::ATTR_KIND_RETURNS_TWICE;
|
|
|
|
case Attribute::SExt:
|
|
|
|
return bitc::ATTR_KIND_S_EXT;
|
|
|
|
case Attribute::StackAlignment:
|
|
|
|
return bitc::ATTR_KIND_STACK_ALIGNMENT;
|
|
|
|
case Attribute::StackProtect:
|
|
|
|
return bitc::ATTR_KIND_STACK_PROTECT;
|
|
|
|
case Attribute::StackProtectReq:
|
|
|
|
return bitc::ATTR_KIND_STACK_PROTECT_REQ;
|
|
|
|
case Attribute::StackProtectStrong:
|
|
|
|
return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
|
Protection against stack-based memory corruption errors using SafeStack
This patch adds the safe stack instrumentation pass to LLVM, which separates
the program stack into a safe stack, which stores return addresses, register
spills, and local variables that are statically verified to be accessed
in a safe way, and the unsafe stack, which stores everything else. Such
separation makes it much harder for an attacker to corrupt objects on the
safe stack, including function pointers stored in spilled registers and
return addresses. You can find more information about the safe stack, as
well as other parts of or control-flow hijack protection technique in our
OSDI paper on code-pointer integrity (http://dslab.epfl.ch/pubs/cpi.pdf)
and our project website (http://levee.epfl.ch).
The overhead of our implementation of the safe stack is very close to zero
(0.01% on the Phoronix benchmarks). This is lower than the overhead of
stack cookies, which are supported by LLVM and are commonly used today,
yet the security guarantees of the safe stack are strictly stronger than
stack cookies. In some cases, the safe stack improves performance due to
better cache locality.
Our current implementation of the safe stack is stable and robust, we
used it to recompile multiple projects on Linux including Chromium, and
we also recompiled the entire FreeBSD user-space system and more than 100
packages. We ran unit tests on the FreeBSD system and many of the packages
and observed no errors caused by the safe stack. The safe stack is also fully
binary compatible with non-instrumented code and can be applied to parts of
a program selectively.
This patch is our implementation of the safe stack on top of LLVM. The
patches make the following changes:
- Add the safestack function attribute, similar to the ssp, sspstrong and
sspreq attributes.
- Add the SafeStack instrumentation pass that applies the safe stack to all
functions that have the safestack attribute. This pass moves all unsafe local
variables to the unsafe stack with a separate stack pointer, whereas all
safe variables remain on the regular stack that is managed by LLVM as usual.
- Invoke the pass as the last stage before code generation (at the same time
the existing cookie-based stack protector pass is invoked).
- Add unit tests for the safe stack.
Original patch by Volodymyr Kuznetsov and others at the Dependable Systems
Lab at EPFL; updates and upstreaming by myself.
Differential Revision: http://reviews.llvm.org/D6094
llvm-svn: 239761
2015-06-16 05:07:11 +08:00
|
|
|
case Attribute::SafeStack:
|
|
|
|
return bitc::ATTR_KIND_SAFESTACK;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::StructRet:
|
|
|
|
return bitc::ATTR_KIND_STRUCT_RET;
|
|
|
|
case Attribute::SanitizeAddress:
|
|
|
|
return bitc::ATTR_KIND_SANITIZE_ADDRESS;
|
|
|
|
case Attribute::SanitizeThread:
|
|
|
|
return bitc::ATTR_KIND_SANITIZE_THREAD;
|
|
|
|
case Attribute::SanitizeMemory:
|
|
|
|
return bitc::ATTR_KIND_SANITIZE_MEMORY;
|
2016-04-02 05:41:15 +08:00
|
|
|
case Attribute::SwiftError:
|
|
|
|
return bitc::ATTR_KIND_SWIFT_ERROR;
|
2016-03-30 01:37:21 +08:00
|
|
|
case Attribute::SwiftSelf:
|
|
|
|
return bitc::ATTR_KIND_SWIFT_SELF;
|
2013-07-26 12:16:55 +08:00
|
|
|
case Attribute::UWTable:
|
|
|
|
return bitc::ATTR_KIND_UW_TABLE;
|
|
|
|
case Attribute::ZExt:
|
|
|
|
return bitc::ATTR_KIND_Z_EXT;
|
|
|
|
case Attribute::EndAttrKinds:
|
|
|
|
llvm_unreachable("Can not encode end-attribute kinds marker.");
|
|
|
|
case Attribute::None:
|
|
|
|
llvm_unreachable("Can not encode none-attribute.");
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Trying to encode unknown attribute");
|
|
|
|
}
|
|
|
|
|
2013-02-11 07:09:32 +08:00
|
|
|
static void WriteAttributeGroupTable(const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
2013-02-12 06:33:26 +08:00
|
|
|
const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups();
|
|
|
|
if (AttrGrps.empty()) return;
|
2013-02-11 07:09:32 +08:00
|
|
|
|
|
|
|
Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3);
|
|
|
|
|
|
|
|
SmallVector<uint64_t, 64> Record;
|
2013-02-12 06:33:26 +08:00
|
|
|
for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) {
|
|
|
|
AttributeSet AS = AttrGrps[i];
|
2013-02-11 07:09:32 +08:00
|
|
|
for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) {
|
|
|
|
AttributeSet A = AS.getSlotAttributes(i);
|
|
|
|
|
2013-02-12 06:33:26 +08:00
|
|
|
Record.push_back(VE.getAttributeGroupID(A));
|
2013-02-11 07:09:32 +08:00
|
|
|
Record.push_back(AS.getSlotIndex(i));
|
|
|
|
|
|
|
|
for (AttributeSet::iterator I = AS.begin(0), E = AS.end(0);
|
|
|
|
I != E; ++I) {
|
|
|
|
Attribute Attr = *I;
|
|
|
|
if (Attr.isEnumAttribute()) {
|
|
|
|
Record.push_back(0);
|
2013-07-26 12:16:55 +08:00
|
|
|
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
|
2014-07-18 14:51:55 +08:00
|
|
|
} else if (Attr.isIntAttribute()) {
|
2013-02-11 07:09:32 +08:00
|
|
|
Record.push_back(1);
|
2013-07-26 12:16:55 +08:00
|
|
|
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
|
2013-02-11 07:09:32 +08:00
|
|
|
Record.push_back(Attr.getValueAsInt());
|
|
|
|
} else {
|
|
|
|
StringRef Kind = Attr.getKindAsString();
|
|
|
|
StringRef Val = Attr.getValueAsString();
|
|
|
|
|
|
|
|
Record.push_back(Val.empty() ? 3 : 4);
|
|
|
|
Record.append(Kind.begin(), Kind.end());
|
|
|
|
Record.push_back(0);
|
|
|
|
if (!Val.empty()) {
|
|
|
|
Record.append(Val.begin(), Val.end());
|
|
|
|
Record.push_back(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2009-09-20 10:20:51 +08:00
|
|
|
static void WriteAttributeTable(const ValueEnumerator &VE,
|
2007-05-04 08:44:52 +08:00
|
|
|
BitstreamWriter &Stream) {
|
2012-12-08 07:16:57 +08:00
|
|
|
const std::vector<AttributeSet> &Attrs = VE.getAttributes();
|
2007-05-04 08:44:52 +08:00
|
|
|
if (Attrs.empty()) return;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-04 10:59:04 +08:00
|
|
|
Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
|
|
|
|
|
|
|
|
SmallVector<uint64_t, 64> Record;
|
|
|
|
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
|
2012-12-08 07:16:57 +08:00
|
|
|
const AttributeSet &A = Attrs[i];
|
2013-02-12 16:13:50 +08:00
|
|
|
for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i)
|
|
|
|
Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i)));
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2013-02-12 16:13:50 +08:00
|
|
|
Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
|
2007-05-04 10:59:04 +08:00
|
|
|
Record.clear();
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-04 10:59:04 +08:00
|
|
|
Stream.ExitBlock();
|
2007-05-04 08:44:52 +08:00
|
|
|
}
|
2007-04-22 14:24:45 +08:00
|
|
|
|
|
|
|
/// WriteTypeTable - Write out the type table for a module.
|
|
|
|
static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
|
|
|
const ValueEnumerator::TypeList &TypeList = VE.getTypes();
|
2009-09-20 10:20:51 +08:00
|
|
|
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
|
2007-04-22 14:24:45 +08:00
|
|
|
SmallVector<uint64_t, 64> TypeVals;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2015-02-25 08:51:52 +08:00
|
|
|
uint64_t NumBits = VE.computeBitsRequiredForTypeIndicies();
|
2011-12-08 08:38:45 +08:00
|
|
|
|
2007-05-05 14:30:12 +08:00
|
|
|
// Abbrev for TYPE_CODE_POINTER.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
|
2011-12-08 08:38:45 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
|
2007-12-12 16:44:39 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0
|
2007-05-05 14:30:12 +08:00
|
|
|
unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 14:30:12 +08:00
|
|
|
// Abbrev for TYPE_CODE_FUNCTION.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
2011-12-08 08:38:45 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
|
|
|
|
|
2007-05-05 14:30:12 +08:00
|
|
|
unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
// Abbrev for TYPE_CODE_STRUCT_ANON.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
2011-12-08 08:38:45 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
|
|
|
|
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
// Abbrev for TYPE_CODE_STRUCT_NAME.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
|
|
|
|
unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
// Abbrev for TYPE_CODE_STRUCT_NAMED.
|
2007-05-05 14:30:12 +08:00
|
|
|
Abbv = new BitCodeAbbrev();
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED));
|
2007-05-05 14:30:12 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
2011-12-08 08:38:45 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
|
|
|
|
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2007-05-05 14:30:12 +08:00
|
|
|
// Abbrev for TYPE_CODE_ARRAY.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // size
|
2011-12-08 08:38:45 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
|
|
|
|
|
2007-05-05 14:30:12 +08:00
|
|
|
unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
// Emit an entry count so the reader can reserve space.
|
|
|
|
TypeVals.push_back(TypeList.size());
|
|
|
|
Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals);
|
|
|
|
TypeVals.clear();
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
// Loop over all of the types, emitting each in turn.
|
|
|
|
for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *T = TypeList[i];
|
2007-04-22 14:24:45 +08:00
|
|
|
int AbbrevToUse = 0;
|
|
|
|
unsigned Code = 0;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
switch (T->getTypeID()) {
|
2012-11-25 23:23:39 +08:00
|
|
|
case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break;
|
|
|
|
case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break;
|
|
|
|
case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break;
|
|
|
|
case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
|
|
|
|
case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break;
|
|
|
|
case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break;
|
2007-08-03 09:03:46 +08:00
|
|
|
case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
|
2012-11-25 23:23:39 +08:00
|
|
|
case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
|
|
|
|
case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
|
|
|
|
case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
|
2015-08-14 13:09:07 +08:00
|
|
|
case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break;
|
2007-04-22 14:24:45 +08:00
|
|
|
case Type::IntegerTyID:
|
|
|
|
// INTEGER: [width]
|
|
|
|
Code = bitc::TYPE_CODE_INTEGER;
|
|
|
|
TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
|
|
|
|
break;
|
2007-12-11 20:20:47 +08:00
|
|
|
case Type::PointerTyID: {
|
2011-07-18 12:54:35 +08:00
|
|
|
PointerType *PTy = cast<PointerType>(T);
|
2007-12-12 16:44:39 +08:00
|
|
|
// POINTER: [pointee type, address space]
|
2007-04-22 14:24:45 +08:00
|
|
|
Code = bitc::TYPE_CODE_POINTER;
|
2007-12-11 16:59:05 +08:00
|
|
|
TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
|
2007-12-12 16:44:39 +08:00
|
|
|
unsigned AddressSpace = PTy->getAddressSpace();
|
|
|
|
TypeVals.push_back(AddressSpace);
|
|
|
|
if (AddressSpace == 0) AbbrevToUse = PtrAbbrev;
|
2007-04-22 14:24:45 +08:00
|
|
|
break;
|
2007-12-11 20:20:47 +08:00
|
|
|
}
|
2007-04-22 14:24:45 +08:00
|
|
|
case Type::FunctionTyID: {
|
2011-07-18 12:54:35 +08:00
|
|
|
FunctionType *FT = cast<FunctionType>(T);
|
2011-11-03 08:14:01 +08:00
|
|
|
// FUNCTION: [isvararg, retty, paramty x N]
|
2007-04-22 14:24:45 +08:00
|
|
|
Code = bitc::TYPE_CODE_FUNCTION;
|
|
|
|
TypeVals.push_back(FT->isVarArg());
|
|
|
|
TypeVals.push_back(VE.getTypeID(FT->getReturnType()));
|
|
|
|
for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i)
|
|
|
|
TypeVals.push_back(VE.getTypeID(FT->getParamType(i)));
|
2007-05-05 14:30:12 +08:00
|
|
|
AbbrevToUse = FunctionAbbrev;
|
2007-04-22 14:24:45 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Type::StructTyID: {
|
2011-07-18 12:54:35 +08:00
|
|
|
StructType *ST = cast<StructType>(T);
|
2007-05-05 14:30:12 +08:00
|
|
|
// STRUCT: [ispacked, eltty x N]
|
2007-04-22 14:24:45 +08:00
|
|
|
TypeVals.push_back(ST->isPacked());
|
2007-05-05 03:11:41 +08:00
|
|
|
// Output all of the element types.
|
2007-04-22 14:24:45 +08:00
|
|
|
for (StructType::element_iterator I = ST->element_begin(),
|
|
|
|
E = ST->element_end(); I != E; ++I)
|
|
|
|
TypeVals.push_back(VE.getTypeID(*I));
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2011-08-13 02:06:37 +08:00
|
|
|
if (ST->isLiteral()) {
|
Land the long talked about "type system rewrite" patch. This
patch brings numerous advantages to LLVM. One way to look at it
is through diffstat:
109 files changed, 3005 insertions(+), 5906 deletions(-)
Removing almost 3K lines of code is a good thing. Other advantages
include:
1. Value::getType() is a simple load that can be CSE'd, not a mutating
union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
uniques them. This means that the compiler doesn't merge them structurally
which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead
"const Type *" everywhere.
Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.
"LLVM 3.0" is the right time to do this.
There are still some cleanups pending after this, this patch is large enough
as-is.
llvm-svn: 134829
2011-07-10 01:41:24 +08:00
|
|
|
Code = bitc::TYPE_CODE_STRUCT_ANON;
|
|
|
|
AbbrevToUse = StructAnonAbbrev;
|
|
|
|
} else {
|
|
|
|
if (ST->isOpaque()) {
|
|
|
|
Code = bitc::TYPE_CODE_OPAQUE;
|
|
|
|
} else {
|
|
|
|
Code = bitc::TYPE_CODE_STRUCT_NAMED;
|
|
|
|
AbbrevToUse = StructNamedAbbrev;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emit the name if it is present.
|
|
|
|
if (!ST->getName().empty())
|
|
|
|
WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(),
|
|
|
|
StructNameAbbrev, Stream);
|
|
|
|
}
|
2007-04-22 14:24:45 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Type::ArrayTyID: {
|
2011-07-18 12:54:35 +08:00
|
|
|
ArrayType *AT = cast<ArrayType>(T);
|
2007-04-22 14:24:45 +08:00
|
|
|
// ARRAY: [numelts, eltty]
|
|
|
|
Code = bitc::TYPE_CODE_ARRAY;
|
|
|
|
TypeVals.push_back(AT->getNumElements());
|
|
|
|
TypeVals.push_back(VE.getTypeID(AT->getElementType()));
|
2007-05-05 14:30:12 +08:00
|
|
|
AbbrevToUse = ArrayAbbrev;
|
2007-04-22 14:24:45 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Type::VectorTyID: {
|
2011-07-18 12:54:35 +08:00
|
|
|
VectorType *VT = cast<VectorType>(T);
|
2007-04-22 14:24:45 +08:00
|
|
|
// VECTOR [numelts, eltty]
|
|
|
|
Code = bitc::TYPE_CODE_VECTOR;
|
|
|
|
TypeVals.push_back(VT->getNumElements());
|
|
|
|
TypeVals.push_back(VE.getTypeID(VT->getElementType()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emit the finished record.
|
|
|
|
Stream.EmitRecord(Code, TypeVals, AbbrevToUse);
|
|
|
|
TypeVals.clear();
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2016-02-07 00:07:35 +08:00
|
|
|
static unsigned getEncodedLinkage(const GlobalValue::LinkageTypes Linkage) {
|
|
|
|
switch (Linkage) {
|
2015-01-09 00:25:01 +08:00
|
|
|
case GlobalValue::ExternalLinkage:
|
|
|
|
return 0;
|
|
|
|
case GlobalValue::WeakAnyLinkage:
|
2015-01-19 23:16:06 +08:00
|
|
|
return 16;
|
2015-01-09 00:25:01 +08:00
|
|
|
case GlobalValue::AppendingLinkage:
|
|
|
|
return 2;
|
|
|
|
case GlobalValue::InternalLinkage:
|
|
|
|
return 3;
|
|
|
|
case GlobalValue::LinkOnceAnyLinkage:
|
2015-01-19 23:16:06 +08:00
|
|
|
return 18;
|
2015-01-09 00:25:01 +08:00
|
|
|
case GlobalValue::ExternalWeakLinkage:
|
|
|
|
return 7;
|
|
|
|
case GlobalValue::CommonLinkage:
|
|
|
|
return 8;
|
|
|
|
case GlobalValue::PrivateLinkage:
|
|
|
|
return 9;
|
|
|
|
case GlobalValue::WeakODRLinkage:
|
2015-01-19 23:16:06 +08:00
|
|
|
return 17;
|
2015-01-09 00:25:01 +08:00
|
|
|
case GlobalValue::LinkOnceODRLinkage:
|
2015-01-19 23:16:06 +08:00
|
|
|
return 19;
|
2015-01-09 00:25:01 +08:00
|
|
|
case GlobalValue::AvailableExternallyLinkage:
|
|
|
|
return 12;
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
2012-01-11 02:08:01 +08:00
|
|
|
llvm_unreachable("Invalid linkage");
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
|
|
|
|
2016-02-07 00:07:35 +08:00
|
|
|
static unsigned getEncodedLinkage(const GlobalValue &GV) {
|
|
|
|
return getEncodedLinkage(GV.getLinkage());
|
|
|
|
}
|
|
|
|
|
2014-05-26 21:38:51 +08:00
|
|
|
static unsigned getEncodedVisibility(const GlobalValue &GV) {
|
|
|
|
switch (GV.getVisibility()) {
|
2007-04-30 04:56:48 +08:00
|
|
|
case GlobalValue::DefaultVisibility: return 0;
|
|
|
|
case GlobalValue::HiddenVisibility: return 1;
|
|
|
|
case GlobalValue::ProtectedVisibility: return 2;
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
2012-01-11 02:08:01 +08:00
|
|
|
llvm_unreachable("Invalid visibility");
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
|
|
|
|
2014-05-26 21:38:51 +08:00
|
|
|
static unsigned getEncodedDLLStorageClass(const GlobalValue &GV) {
|
|
|
|
switch (GV.getDLLStorageClass()) {
|
2014-01-14 23:22:47 +08:00
|
|
|
case GlobalValue::DefaultStorageClass: return 0;
|
|
|
|
case GlobalValue::DLLImportStorageClass: return 1;
|
|
|
|
case GlobalValue::DLLExportStorageClass: return 2;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Invalid DLL storage class");
|
|
|
|
}
|
|
|
|
|
2014-05-29 02:15:43 +08:00
|
|
|
static unsigned getEncodedThreadLocalMode(const GlobalValue &GV) {
|
2014-05-26 21:38:51 +08:00
|
|
|
switch (GV.getThreadLocalMode()) {
|
2012-06-23 19:37:03 +08:00
|
|
|
case GlobalVariable::NotThreadLocal: return 0;
|
|
|
|
case GlobalVariable::GeneralDynamicTLSModel: return 1;
|
|
|
|
case GlobalVariable::LocalDynamicTLSModel: return 2;
|
|
|
|
case GlobalVariable::InitialExecTLSModel: return 3;
|
|
|
|
case GlobalVariable::LocalExecTLSModel: return 4;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Invalid TLS model");
|
|
|
|
}
|
|
|
|
|
2014-06-28 02:19:56 +08:00
|
|
|
static unsigned getEncodedComdatSelectionKind(const Comdat &C) {
|
|
|
|
switch (C.getSelectionKind()) {
|
|
|
|
case Comdat::Any:
|
|
|
|
return bitc::COMDAT_SELECTION_KIND_ANY;
|
|
|
|
case Comdat::ExactMatch:
|
|
|
|
return bitc::COMDAT_SELECTION_KIND_EXACT_MATCH;
|
|
|
|
case Comdat::Largest:
|
|
|
|
return bitc::COMDAT_SELECTION_KIND_LARGEST;
|
|
|
|
case Comdat::NoDuplicates:
|
|
|
|
return bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES;
|
|
|
|
case Comdat::SameSize:
|
|
|
|
return bitc::COMDAT_SELECTION_KIND_SAME_SIZE;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Invalid selection kind");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void writeComdats(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
2016-03-13 16:01:03 +08:00
|
|
|
SmallVector<unsigned, 64> Vals;
|
2014-06-28 02:19:56 +08:00
|
|
|
for (const Comdat *C : VE.getComdats()) {
|
|
|
|
// COMDAT: [selection_kind, name]
|
|
|
|
Vals.push_back(getEncodedComdatSelectionKind(*C));
|
2015-01-15 02:25:45 +08:00
|
|
|
size_t Size = C->getName().size();
|
2016-03-13 16:01:03 +08:00
|
|
|
assert(isUInt<32>(Size));
|
2015-01-15 02:25:45 +08:00
|
|
|
Vals.push_back(Size);
|
2014-06-28 02:19:56 +08:00
|
|
|
for (char Chr : C->getName())
|
|
|
|
Vals.push_back((unsigned char)Chr);
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_COMDAT, Vals, /*AbbrevToUse=*/0);
|
|
|
|
Vals.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-18 04:12:00 +08:00
|
|
|
/// Write a record that will eventually hold the word offset of the
|
|
|
|
/// module-level VST. For now the offset is 0, which will be backpatched
|
|
|
|
/// after the real VST is written. Returns the bit offset to backpatch.
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
static uint64_t WriteValueSymbolTableForwardDecl(BitstreamWriter &Stream) {
|
2015-09-18 04:12:00 +08:00
|
|
|
// Write a placeholder value in for the offset of the real VST,
|
|
|
|
// which is written after the function blocks so that it can include
|
|
|
|
// the offset of each function. The placeholder offset will be
|
|
|
|
// updated when the real VST is written.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_VSTOFFSET));
|
|
|
|
// Blocks are 32-bit aligned, so we can use a 32-bit word offset to
|
|
|
|
// hold the real VST offset. Must use fixed instead of VBR as we don't
|
|
|
|
// know how many VBR chunks to reserve ahead of time.
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
|
|
|
|
unsigned VSTOffsetAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
// Emit the placeholder
|
|
|
|
uint64_t Vals[] = {bitc::MODULE_CODE_VSTOFFSET, 0};
|
|
|
|
Stream.EmitRecordWithAbbrev(VSTOffsetAbbrev, Vals);
|
|
|
|
|
|
|
|
// Compute and return the bit offset to the placeholder, which will be
|
|
|
|
// patched when the real VST is written. We can simply subtract the 32-bit
|
|
|
|
// fixed size from the current bit number to get the location to backpatch.
|
|
|
|
return Stream.GetCurrentBitNo() - 32;
|
|
|
|
}
|
|
|
|
|
2016-02-11 05:55:02 +08:00
|
|
|
enum StringEncoding { SE_Char6, SE_Fixed7, SE_Fixed8 };
|
|
|
|
|
|
|
|
/// Determine the encoding to use for the given string name and length.
|
|
|
|
static StringEncoding getStringEncoding(const char *Str, unsigned StrLen) {
|
|
|
|
bool isChar6 = true;
|
|
|
|
for (const char *C = Str, *E = C + StrLen; C != E; ++C) {
|
|
|
|
if (isChar6)
|
|
|
|
isChar6 = BitCodeAbbrevOp::isChar6(*C);
|
|
|
|
if ((unsigned char)*C & 128)
|
|
|
|
// don't bother scanning the rest.
|
|
|
|
return SE_Fixed8;
|
|
|
|
}
|
|
|
|
if (isChar6)
|
|
|
|
return SE_Char6;
|
|
|
|
else
|
|
|
|
return SE_Fixed7;
|
|
|
|
}
|
|
|
|
|
2015-09-18 04:12:00 +08:00
|
|
|
/// Emit top-level description of module, including target triple, inline asm,
|
|
|
|
/// descriptors for global variables, and function prototype info.
|
|
|
|
/// Returns the bit offset to backpatch with the location of the real VST.
|
|
|
|
static uint64_t WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
2007-04-22 14:24:45 +08:00
|
|
|
// Emit various pieces of data attached to a module.
|
|
|
|
if (!M->getTargetTriple().empty())
|
|
|
|
WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
|
|
|
|
0/*TODO*/, Stream);
|
2014-02-26 04:01:08 +08:00
|
|
|
const std::string &DL = M->getDataLayoutStr();
|
|
|
|
if (!DL.empty())
|
|
|
|
WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream);
|
2007-04-22 14:24:45 +08:00
|
|
|
if (!M->getModuleInlineAsm().empty())
|
|
|
|
WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
|
|
|
|
0/*TODO*/, Stream);
|
|
|
|
|
2008-08-18 02:44:35 +08:00
|
|
|
// Emit information about sections and GC, computing how many there are. Also
|
|
|
|
// compute the maximum alignment value.
|
2007-04-22 14:24:45 +08:00
|
|
|
std::map<std::string, unsigned> SectionMap;
|
2008-08-18 02:44:35 +08:00
|
|
|
std::map<std::string, unsigned> GCMap;
|
2007-04-24 00:04:05 +08:00
|
|
|
unsigned MaxAlignment = 0;
|
2007-04-24 02:58:34 +08:00
|
|
|
unsigned MaxGlobalType = 0;
|
2014-05-26 21:38:51 +08:00
|
|
|
for (const GlobalValue &GV : M->globals()) {
|
|
|
|
MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
|
2015-04-28 03:58:56 +08:00
|
|
|
MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType()));
|
2014-05-26 21:38:51 +08:00
|
|
|
if (GV.hasSection()) {
|
2011-08-13 00:45:18 +08:00
|
|
|
// Give section names unique ID's.
|
2014-05-26 21:38:51 +08:00
|
|
|
unsigned &Entry = SectionMap[GV.getSection()];
|
2011-08-13 00:45:18 +08:00
|
|
|
if (!Entry) {
|
2014-05-26 21:38:51 +08:00
|
|
|
WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(),
|
2011-08-13 00:45:18 +08:00
|
|
|
0/*TODO*/, Stream);
|
|
|
|
Entry = SectionMap.size();
|
|
|
|
}
|
|
|
|
}
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
2014-05-26 21:38:51 +08:00
|
|
|
for (const Function &F : *M) {
|
|
|
|
MaxAlignment = std::max(MaxAlignment, F.getAlignment());
|
|
|
|
if (F.hasSection()) {
|
2007-12-10 11:18:06 +08:00
|
|
|
// Give section names unique ID's.
|
2014-05-26 21:38:51 +08:00
|
|
|
unsigned &Entry = SectionMap[F.getSection()];
|
2007-12-10 11:18:06 +08:00
|
|
|
if (!Entry) {
|
2014-05-26 21:38:51 +08:00
|
|
|
WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(),
|
2007-12-10 11:18:06 +08:00
|
|
|
0/*TODO*/, Stream);
|
|
|
|
Entry = SectionMap.size();
|
|
|
|
}
|
|
|
|
}
|
2014-05-26 21:38:51 +08:00
|
|
|
if (F.hasGC()) {
|
2008-08-18 02:44:35 +08:00
|
|
|
// Same for GC names.
|
2014-05-26 21:38:51 +08:00
|
|
|
unsigned &Entry = GCMap[F.getGC()];
|
2007-12-10 11:18:06 +08:00
|
|
|
if (!Entry) {
|
2014-05-26 21:38:51 +08:00
|
|
|
WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(),
|
2007-12-10 11:18:06 +08:00
|
|
|
0/*TODO*/, Stream);
|
2008-08-18 02:44:35 +08:00
|
|
|
Entry = GCMap.size();
|
2007-12-10 11:18:06 +08:00
|
|
|
}
|
|
|
|
}
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-24 00:04:05 +08:00
|
|
|
// Emit abbrev for globals, now that we know # sections and max alignment.
|
|
|
|
unsigned SimpleGVarAbbrev = 0;
|
2009-09-20 10:20:51 +08:00
|
|
|
if (!M->global_empty()) {
|
2007-04-24 00:04:05 +08:00
|
|
|
// Add an abbrev for common globals with no visibility or thread localness.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR));
|
2007-05-05 04:34:50 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
|
2007-04-24 02:58:34 +08:00
|
|
|
Log2_32_Ceil(MaxGlobalType+1)));
|
2015-04-28 03:58:56 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddrSpace << 2
|
|
|
|
//| explicitType << 1
|
|
|
|
//| constant
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer.
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // Linkage.
|
|
|
|
if (MaxAlignment == 0) // Alignment.
|
2007-04-24 00:04:05 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(0));
|
|
|
|
else {
|
|
|
|
unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1;
|
2007-05-05 04:34:50 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
|
2007-04-24 02:58:34 +08:00
|
|
|
Log2_32_Ceil(MaxEncAlignment+1)));
|
2007-04-24 00:04:05 +08:00
|
|
|
}
|
|
|
|
if (SectionMap.empty()) // Section.
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(0));
|
|
|
|
else
|
2007-05-05 04:34:50 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
|
2007-04-24 11:29:47 +08:00
|
|
|
Log2_32_Ceil(SectionMap.size()+1)));
|
2007-04-24 00:04:05 +08:00
|
|
|
// Don't bother emitting vis + thread local.
|
|
|
|
SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
// Emit the global variable information.
|
|
|
|
SmallVector<unsigned, 64> Vals;
|
2014-05-26 21:38:51 +08:00
|
|
|
for (const GlobalVariable &GV : M->globals()) {
|
2007-04-24 00:04:05 +08:00
|
|
|
unsigned AbbrevToUse = 0;
|
|
|
|
|
2009-09-20 10:20:51 +08:00
|
|
|
// GLOBALVAR: [type, isconst, initid,
|
2011-01-09 00:42:36 +08:00
|
|
|
// linkage, alignment, section, visibility, threadlocal,
|
2015-02-04 08:42:45 +08:00
|
|
|
// unnamed_addr, externally_initialized, dllstorageclass,
|
|
|
|
// comdat]
|
2015-04-28 03:58:56 +08:00
|
|
|
Vals.push_back(VE.getTypeID(GV.getValueType()));
|
|
|
|
Vals.push_back(GV.getType()->getAddressSpace() << 2 | 2 | GV.isConstant());
|
2014-05-26 21:38:51 +08:00
|
|
|
Vals.push_back(GV.isDeclaration() ? 0 :
|
|
|
|
(VE.getValueID(GV.getInitializer()) + 1));
|
2007-04-22 14:24:45 +08:00
|
|
|
Vals.push_back(getEncodedLinkage(GV));
|
2014-05-26 21:38:51 +08:00
|
|
|
Vals.push_back(Log2_32(GV.getAlignment())+1);
|
|
|
|
Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
|
|
|
|
if (GV.isThreadLocal() ||
|
|
|
|
GV.getVisibility() != GlobalValue::DefaultVisibility ||
|
|
|
|
GV.hasUnnamedAddr() || GV.isExternallyInitialized() ||
|
2014-06-28 02:19:56 +08:00
|
|
|
GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
|
|
|
|
GV.hasComdat()) {
|
2007-04-24 00:04:05 +08:00
|
|
|
Vals.push_back(getEncodedVisibility(GV));
|
2012-06-23 19:37:03 +08:00
|
|
|
Vals.push_back(getEncodedThreadLocalMode(GV));
|
2014-05-26 21:38:51 +08:00
|
|
|
Vals.push_back(GV.hasUnnamedAddr());
|
|
|
|
Vals.push_back(GV.isExternallyInitialized());
|
2014-01-14 23:22:47 +08:00
|
|
|
Vals.push_back(getEncodedDLLStorageClass(GV));
|
2014-06-28 02:19:56 +08:00
|
|
|
Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0);
|
2007-04-24 00:04:05 +08:00
|
|
|
} else {
|
|
|
|
AbbrevToUse = SimpleGVarAbbrev;
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse);
|
|
|
|
Vals.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emit the function proto information.
|
2014-05-26 21:38:51 +08:00
|
|
|
for (const Function &F : *M) {
|
2011-12-08 07:57:55 +08:00
|
|
|
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
|
2014-12-03 10:08:38 +08:00
|
|
|
// section, visibility, gc, unnamed_addr, prologuedata,
|
2015-06-18 04:52:32 +08:00
|
|
|
// dllstorageclass, comdat, prefixdata, personalityfn]
|
2015-04-18 00:28:26 +08:00
|
|
|
Vals.push_back(VE.getTypeID(F.getFunctionType()));
|
2014-05-26 21:38:51 +08:00
|
|
|
Vals.push_back(F.getCallingConv());
|
|
|
|
Vals.push_back(F.isDeclaration());
|
2007-04-22 14:24:45 +08:00
|
|
|
Vals.push_back(getEncodedLinkage(F));
|
2014-05-26 21:38:51 +08:00
|
|
|
Vals.push_back(VE.getAttributeID(F.getAttributes()));
|
|
|
|
Vals.push_back(Log2_32(F.getAlignment())+1);
|
|
|
|
Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
|
2007-04-22 14:24:45 +08:00
|
|
|
Vals.push_back(getEncodedVisibility(F));
|
2014-05-26 21:38:51 +08:00
|
|
|
Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
|
|
|
|
Vals.push_back(F.hasUnnamedAddr());
|
2014-12-03 10:08:38 +08:00
|
|
|
Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1)
|
|
|
|
: 0);
|
2014-01-14 23:22:47 +08:00
|
|
|
Vals.push_back(getEncodedDLLStorageClass(F));
|
2014-06-28 02:19:56 +08:00
|
|
|
Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0);
|
2014-12-03 10:08:38 +08:00
|
|
|
Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1)
|
|
|
|
: 0);
|
2015-06-18 04:52:32 +08:00
|
|
|
Vals.push_back(
|
|
|
|
F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
unsigned AbbrevToUse = 0;
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
|
|
|
|
Vals.clear();
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-26 10:46:40 +08:00
|
|
|
// Emit the alias information.
|
2014-05-26 21:38:51 +08:00
|
|
|
for (const GlobalAlias &A : M->aliases()) {
|
2011-12-08 08:11:31 +08:00
|
|
|
// ALIAS: [alias type, aliasee val#, linkage, visibility]
|
2015-09-18 06:18:59 +08:00
|
|
|
Vals.push_back(VE.getTypeID(A.getValueType()));
|
|
|
|
Vals.push_back(A.getType()->getAddressSpace());
|
2014-05-26 21:38:51 +08:00
|
|
|
Vals.push_back(VE.getValueID(A.getAliasee()));
|
|
|
|
Vals.push_back(getEncodedLinkage(A));
|
|
|
|
Vals.push_back(getEncodedVisibility(A));
|
|
|
|
Vals.push_back(getEncodedDLLStorageClass(A));
|
2014-06-06 09:20:28 +08:00
|
|
|
Vals.push_back(getEncodedThreadLocalMode(A));
|
|
|
|
Vals.push_back(A.hasUnnamedAddr());
|
2007-04-26 10:46:40 +08:00
|
|
|
unsigned AbbrevToUse = 0;
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
|
|
|
|
Vals.clear();
|
|
|
|
}
|
2015-09-18 04:12:00 +08:00
|
|
|
|
2016-04-07 20:32:19 +08:00
|
|
|
// Emit the ifunc information.
|
|
|
|
for (const GlobalIFunc &I : M->ifuncs()) {
|
|
|
|
// IFUNC: [ifunc type, address space, resolver val#, linkage, visibility]
|
|
|
|
Vals.push_back(VE.getTypeID(I.getValueType()));
|
|
|
|
Vals.push_back(I.getType()->getAddressSpace());
|
|
|
|
Vals.push_back(VE.getValueID(I.getResolver()));
|
|
|
|
Vals.push_back(getEncodedLinkage(I));
|
|
|
|
Vals.push_back(getEncodedVisibility(I));
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_IFUNC, Vals);
|
|
|
|
Vals.clear();
|
|
|
|
}
|
|
|
|
|
2016-02-11 05:55:02 +08:00
|
|
|
// Emit the module's source file name.
|
|
|
|
{
|
2016-02-17 06:07:03 +08:00
|
|
|
StringEncoding Bits = getStringEncoding(M->getSourceFileName().data(),
|
|
|
|
M->getSourceFileName().size());
|
2016-02-11 05:55:02 +08:00
|
|
|
BitCodeAbbrevOp AbbrevOpToUse = BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8);
|
|
|
|
if (Bits == SE_Char6)
|
|
|
|
AbbrevOpToUse = BitCodeAbbrevOp(BitCodeAbbrevOp::Char6);
|
|
|
|
else if (Bits == SE_Fixed7)
|
|
|
|
AbbrevOpToUse = BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7);
|
|
|
|
|
|
|
|
// MODULE_CODE_SOURCE_FILENAME: [namechar x N]
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_SOURCE_FILENAME));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(AbbrevOpToUse);
|
|
|
|
unsigned FilenameAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
for (const auto P : M->getSourceFileName())
|
|
|
|
Vals.push_back((unsigned char)P);
|
|
|
|
|
|
|
|
// Emit the finished record.
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_SOURCE_FILENAME, Vals, FilenameAbbrev);
|
|
|
|
Vals.clear();
|
|
|
|
}
|
2015-11-20 22:51:27 +08:00
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// If we have a VST, write the VSTOFFSET record placeholder and return
|
|
|
|
// its offset.
|
|
|
|
if (M->getValueSymbolTable().empty())
|
|
|
|
return 0;
|
|
|
|
return WriteValueSymbolTableForwardDecl(Stream);
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
|
|
|
|
2009-07-21 05:19:07 +08:00
|
|
|
static uint64_t GetOptimizationFlags(const Value *V) {
|
|
|
|
uint64_t Flags = 0;
|
|
|
|
|
2014-10-16 01:45:13 +08:00
|
|
|
if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) {
|
2009-08-21 01:11:38 +08:00
|
|
|
if (OBO->hasNoSignedWrap())
|
|
|
|
Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
|
|
|
|
if (OBO->hasNoUnsignedWrap())
|
|
|
|
Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
|
2014-10-16 01:45:13 +08:00
|
|
|
} else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) {
|
2011-02-07 05:44:57 +08:00
|
|
|
if (PEO->isExact())
|
|
|
|
Flags |= 1 << bitc::PEO_EXACT;
|
2014-10-16 01:45:13 +08:00
|
|
|
} else if (const auto *FPMO = dyn_cast<FPMathOperator>(V)) {
|
2012-11-27 08:43:38 +08:00
|
|
|
if (FPMO->hasUnsafeAlgebra())
|
2012-12-10 05:12:04 +08:00
|
|
|
Flags |= FastMathFlags::UnsafeAlgebra;
|
2012-11-27 08:43:38 +08:00
|
|
|
if (FPMO->hasNoNaNs())
|
2012-12-10 05:12:04 +08:00
|
|
|
Flags |= FastMathFlags::NoNaNs;
|
2012-11-27 08:43:38 +08:00
|
|
|
if (FPMO->hasNoInfs())
|
2012-12-10 05:12:04 +08:00
|
|
|
Flags |= FastMathFlags::NoInfs;
|
2012-11-27 08:43:38 +08:00
|
|
|
if (FPMO->hasNoSignedZeros())
|
2012-12-10 05:12:04 +08:00
|
|
|
Flags |= FastMathFlags::NoSignedZeros;
|
2012-11-27 08:43:38 +08:00
|
|
|
if (FPMO->hasAllowReciprocal())
|
2012-12-10 05:12:04 +08:00
|
|
|
Flags |= FastMathFlags::AllowReciprocal;
|
2009-07-21 05:19:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Flags;
|
|
|
|
}
|
2007-04-22 14:24:45 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeValueAsMetadata(const ValueAsMetadata *MD,
|
2014-12-12 07:02:24 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record) {
|
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
|
|
|
// Mimic an MDNode with a value as one operand.
|
|
|
|
Value *V = MD->getValue();
|
|
|
|
Record.push_back(VE.getTypeID(V->getType()));
|
|
|
|
Record.push_back(VE.getValueID(V));
|
2014-12-12 07:02:24 +08:00
|
|
|
Stream.EmitRecord(bitc::METADATA_VALUE, Record, 0);
|
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
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeMDTuple(const MDTuple *N, const ValueEnumerator &VE,
|
2015-01-20 09:01:53 +08:00
|
|
|
BitstreamWriter &Stream,
|
2015-01-20 09:03:09 +08:00
|
|
|
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
|
2009-12-31 09:22:29 +08:00
|
|
|
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
|
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
|
|
|
Metadata *MD = N->getOperand(i);
|
2015-01-20 09:00:23 +08:00
|
|
|
assert(!(MD && isa<LocalAsMetadata>(MD)) &&
|
|
|
|
"Unexpected function-local metadata");
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(MD));
|
2009-08-04 13:01:35 +08:00
|
|
|
}
|
2015-01-09 06:38:29 +08:00
|
|
|
Stream.EmitRecord(N->isDistinct() ? bitc::METADATA_DISTINCT_NODE
|
|
|
|
: bitc::METADATA_NODE,
|
2015-01-20 09:03:09 +08:00
|
|
|
Record, Abbrev);
|
2009-08-04 13:01:35 +08:00
|
|
|
Record.clear();
|
|
|
|
}
|
2009-08-04 10:26:56 +08:00
|
|
|
|
2016-03-25 00:25:51 +08:00
|
|
|
static unsigned createDILocationAbbrev(BitstreamWriter &Stream) {
|
|
|
|
// Assume the column is usually under 128, and always output the inlined-at
|
|
|
|
// location (it's never more expensive than building an array size 1).
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
return Stream.EmitAbbrev(Abbv);
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDILocation(const DILocation *N, const ValueEnumerator &VE,
|
2015-01-14 05:10:44 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
2016-03-25 00:25:51 +08:00
|
|
|
unsigned &Abbrev) {
|
|
|
|
if (!Abbrev)
|
|
|
|
Abbrev = createDILocationAbbrev(Stream);
|
|
|
|
|
2015-01-14 05:10:44 +08:00
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(N->getColumn());
|
|
|
|
Record.push_back(VE.getMetadataID(N->getScope()));
|
2015-01-20 09:00:23 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
|
2015-01-14 05:10:44 +08:00
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
2016-03-25 00:30:18 +08:00
|
|
|
static unsigned createGenericDINodeAbbrev(BitstreamWriter &Stream) {
|
|
|
|
// Assume the column is usually under 128, and always output the inlined-at
|
|
|
|
// location (it's never more expensive than building an array size 1).
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_GENERIC_DEBUG));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
return Stream.EmitAbbrev(Abbv);
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeGenericDINode(const GenericDINode *N,
|
2015-04-30 00:38:44 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
2016-03-25 00:30:18 +08:00
|
|
|
unsigned &Abbrev) {
|
|
|
|
if (!Abbrev)
|
|
|
|
Abbrev = createGenericDINodeAbbrev(Stream);
|
|
|
|
|
2015-02-04 05:54:14 +08:00
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getTag());
|
|
|
|
Record.push_back(0); // Per-tag version field; unused for now.
|
|
|
|
|
|
|
|
for (auto &I : N->operands())
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(I));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_GENERIC_DEBUG, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-01-20 09:03:09 +08:00
|
|
|
}
|
|
|
|
|
2015-02-13 09:10:38 +08:00
|
|
|
static uint64_t rotateSign(int64_t I) {
|
|
|
|
uint64_t U = I;
|
|
|
|
return I < 0 ? ~(U << 1) : U << 1;
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDISubrange(const DISubrange *N, const ValueEnumerator &,
|
2015-02-13 09:10:38 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getCount());
|
2015-04-07 08:39:59 +08:00
|
|
|
Record.push_back(rotateSign(N->getLowerBound()));
|
2015-02-13 09:10:38 +08:00
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:10:38 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIEnumerator(const DIEnumerator *N, const ValueEnumerator &VE,
|
2015-02-13 09:14:11 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(rotateSign(N->getValue()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_ENUMERATOR, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:14:11 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIBasicType(const DIBasicType *N, const ValueEnumerator &VE,
|
2015-02-13 09:14:58 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getTag());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(N->getSizeInBits());
|
|
|
|
Record.push_back(N->getAlignInBits());
|
|
|
|
Record.push_back(N->getEncoding());
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:14:58 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIDerivedType(const DIDerivedType *N,
|
2015-02-13 09:20:38 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getTag());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
2015-02-20 11:17:58 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
|
2015-02-13 09:20:38 +08:00
|
|
|
Record.push_back(N->getSizeInBits());
|
|
|
|
Record.push_back(N->getAlignInBits());
|
|
|
|
Record.push_back(N->getOffsetInBits());
|
|
|
|
Record.push_back(N->getFlags());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getExtraData()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:20:38 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDICompositeType(const DICompositeType *N,
|
2015-02-13 09:20:38 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getTag());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
|
|
|
|
Record.push_back(N->getSizeInBits());
|
|
|
|
Record.push_back(N->getAlignInBits());
|
|
|
|
Record.push_back(N->getOffsetInBits());
|
|
|
|
Record.push_back(N->getFlags());
|
2015-04-08 00:50:39 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getElements().get()));
|
2015-02-13 09:20:38 +08:00
|
|
|
Record.push_back(N->getRuntimeLang());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder()));
|
2015-04-08 00:50:39 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
|
2015-02-13 09:20:38 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:20:38 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDISubroutineType(const DISubroutineType *N,
|
2015-02-13 09:22:59 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getFlags());
|
2015-04-08 00:50:39 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getTypeArray().get()));
|
2015-02-13 09:22:59 +08:00
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:19:14 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIFile(const DIFile *N, const ValueEnumerator &VE,
|
2015-02-13 09:19:14 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawFilename()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawDirectory()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:19:14 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDICompileUnit(const DICompileUnit *N,
|
2015-02-13 09:25:10 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
2015-08-04 01:26:41 +08:00
|
|
|
assert(N->isDistinct() && "Expected distinct compile units");
|
|
|
|
Record.push_back(/* IsDistinct */ true);
|
2015-02-13 09:25:10 +08:00
|
|
|
Record.push_back(N->getSourceLanguage());
|
2015-02-20 11:17:58 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
2015-02-13 09:25:10 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawProducer()));
|
|
|
|
Record.push_back(N->isOptimized());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawFlags()));
|
|
|
|
Record.push_back(N->getRuntimeVersion());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawSplitDebugFilename()));
|
|
|
|
Record.push_back(N->getEmissionKind());
|
2015-04-08 00:50:39 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getEnumTypes().get()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRetainedTypes().get()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getSubprograms().get()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get()));
|
2015-05-22 04:37:30 +08:00
|
|
|
Record.push_back(N->getDWOId());
|
2015-12-10 20:56:35 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getMacros().get()));
|
2015-02-13 09:25:10 +08:00
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:25:10 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDISubprogram(const DISubprogram *N, const ValueEnumerator &VE,
|
2015-04-30 00:38:44 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
2015-02-13 09:26:47 +08:00
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getType()));
|
|
|
|
Record.push_back(N->isLocalToUnit());
|
|
|
|
Record.push_back(N->isDefinition());
|
|
|
|
Record.push_back(N->getScopeLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getContainingType()));
|
|
|
|
Record.push_back(N->getVirtuality());
|
|
|
|
Record.push_back(N->getVirtualIndex());
|
|
|
|
Record.push_back(N->getFlags());
|
|
|
|
Record.push_back(N->isOptimized());
|
2015-04-08 00:50:39 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
|
2015-02-13 09:26:47 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getDeclaration()));
|
2015-04-08 00:50:39 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getVariables().get()));
|
2015-02-13 09:26:47 +08:00
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:26:47 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDILexicalBlock(const DILexicalBlock *N,
|
2015-04-30 00:38:44 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
2015-02-13 09:29:28 +08:00
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(N->getColumn());
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:29:28 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDILexicalBlockFile(const DILexicalBlockFile *N,
|
2015-02-13 09:30:42 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getDiscriminator());
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK_FILE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:30:42 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDINamespace(const DINamespace *N, const ValueEnumerator &VE,
|
2015-02-13 09:32:09 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_NAMESPACE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:32:09 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIMacro(const DIMacro *N, const ValueEnumerator &VE,
|
2015-12-10 20:56:35 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getMacinfoType());
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawValue()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_MACRO, Record, Abbrev);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIMacroFile(const DIMacroFile *N, const ValueEnumerator &VE,
|
2015-12-10 20:56:35 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getMacinfoType());
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getElements().get()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_MACRO_FILE, Record, Abbrev);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIModule(const DIModule *N, const ValueEnumerator &VE,
|
2015-06-30 07:03:47 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
for (auto &I : N->operands())
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(I));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_MODULE, Record, Abbrev);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDITemplateTypeParameter(const DITemplateTypeParameter *N,
|
2015-02-13 09:34:32 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getType()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_TEMPLATE_TYPE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:34:32 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDITemplateValueParameter(const DITemplateValueParameter *N,
|
2015-02-13 09:34:32 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getTag());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getType()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getValue()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_TEMPLATE_VALUE, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:34:32 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIGlobalVariable(const DIGlobalVariable *N,
|
2015-02-13 09:35:40 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getType()));
|
|
|
|
Record.push_back(N->isLocalToUnit());
|
|
|
|
Record.push_back(N->isDefinition());
|
2015-04-12 04:27:40 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawVariable()));
|
2015-02-13 09:35:40 +08:00
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:35:40 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDILocalVariable(const DILocalVariable *N,
|
2015-02-13 09:39:44 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getType()));
|
|
|
|
Record.push_back(N->getArg());
|
|
|
|
Record.push_back(N->getFlags());
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_LOCAL_VAR, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:39:44 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIExpression(const DIExpression *N, const ValueEnumerator &,
|
2015-02-13 09:42:09 +08:00
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.reserve(N->getElements().size() + 1);
|
|
|
|
|
|
|
|
Record.push_back(N->isDistinct());
|
2015-02-17 23:29:18 +08:00
|
|
|
Record.append(N->elements_begin(), N->elements_end());
|
2015-02-13 09:42:09 +08:00
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:42:09 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIObjCProperty(const DIObjCProperty *N,
|
2015-04-30 00:38:44 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
2015-02-13 09:43:22 +08:00
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawSetterName()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawGetterName()));
|
|
|
|
Record.push_back(N->getAttributes());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getType()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_OBJC_PROPERTY, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
2015-02-13 09:43:22 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeDIImportedEntity(const DIImportedEntity *N,
|
2015-02-13 09:46:02 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record,
|
|
|
|
unsigned Abbrev) {
|
|
|
|
Record.push_back(N->isDistinct());
|
|
|
|
Record.push_back(N->getTag());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getEntity()));
|
|
|
|
Record.push_back(N->getLine());
|
|
|
|
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::METADATA_IMPORTED_ENTITY, Record, Abbrev);
|
|
|
|
Record.clear();
|
2015-02-10 08:52:32 +08:00
|
|
|
}
|
|
|
|
|
2016-03-25 00:16:08 +08:00
|
|
|
static unsigned createNamedMetadataAbbrev(BitstreamWriter &Stream) {
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
|
|
|
|
return Stream.EmitAbbrev(Abbv);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void writeNamedMetadata(const Module &M, const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record) {
|
|
|
|
if (M.named_metadata_empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
unsigned Abbrev = createNamedMetadataAbbrev(Stream);
|
|
|
|
for (const NamedMDNode &NMD : M.named_metadata()) {
|
|
|
|
// Write name.
|
|
|
|
StringRef Str = NMD.getName();
|
|
|
|
Record.append(Str.bytes_begin(), Str.bytes_end());
|
|
|
|
Stream.EmitRecord(bitc::METADATA_NAME, Record, Abbrev);
|
|
|
|
Record.clear();
|
|
|
|
|
|
|
|
// Write named metadata operands.
|
|
|
|
for (const MDNode *N : NMD.operands())
|
|
|
|
Record.push_back(VE.getMetadataID(N));
|
|
|
|
Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static unsigned createMetadataStringsAbbrev(BitstreamWriter &Stream) {
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRINGS));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of strings
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // offset to chars
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
|
|
|
return Stream.EmitAbbrev(Abbv);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write out a record for MDString.
|
|
|
|
///
|
|
|
|
/// All the metadata strings in a metadata block are emitted in a single
|
|
|
|
/// record. The sizes and strings themselves are shoved into a blob.
|
|
|
|
static void writeMetadataStrings(ArrayRef<const Metadata *> Strings,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record) {
|
|
|
|
if (Strings.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Start the record with the number of strings.
|
|
|
|
Record.push_back(bitc::METADATA_STRINGS);
|
|
|
|
Record.push_back(Strings.size());
|
|
|
|
|
|
|
|
// Emit the sizes of the strings in the blob.
|
|
|
|
SmallString<256> Blob;
|
|
|
|
{
|
|
|
|
BitstreamWriter W(Blob);
|
|
|
|
for (const Metadata *MD : Strings)
|
|
|
|
W.EmitVBR(cast<MDString>(MD)->getLength(), 6);
|
|
|
|
W.FlushToWord();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the offset to the strings to the record.
|
|
|
|
Record.push_back(Blob.size());
|
|
|
|
|
|
|
|
// Add the strings to the blob.
|
|
|
|
for (const Metadata *MD : Strings)
|
|
|
|
Blob.append(cast<MDString>(MD)->getString());
|
|
|
|
|
|
|
|
// Emit the final record.
|
|
|
|
Stream.EmitRecordWithBlob(createMetadataStringsAbbrev(Stream), Record, Blob);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
2016-03-28 07:53:30 +08:00
|
|
|
static void writeMetadataRecords(ArrayRef<const Metadata *> MDs,
|
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<uint64_t> &Record) {
|
|
|
|
if (MDs.empty())
|
2015-01-13 06:30:34 +08:00
|
|
|
return;
|
|
|
|
|
2015-02-05 05:54:12 +08:00
|
|
|
// Initialize MDNode abbreviations.
|
|
|
|
#define HANDLE_MDNODE_LEAF(CLASS) unsigned CLASS##Abbrev = 0;
|
|
|
|
#include "llvm/IR/Metadata.def"
|
|
|
|
|
2016-03-28 07:53:30 +08:00
|
|
|
for (const Metadata *MD : MDs) {
|
2015-01-13 06:31:35 +08:00
|
|
|
if (const MDNode *N = dyn_cast<MDNode>(MD)) {
|
2015-03-17 08:16:35 +08:00
|
|
|
assert(N->isResolved() && "Expected forward references to be resolved");
|
|
|
|
|
2015-01-20 09:03:09 +08:00
|
|
|
switch (N->getMetadataID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Invalid MDNode subclass");
|
|
|
|
#define HANDLE_MDNODE_LEAF(CLASS) \
|
|
|
|
case Metadata::CLASS##Kind: \
|
2016-03-28 07:56:04 +08:00
|
|
|
write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev); \
|
2015-01-20 09:03:09 +08:00
|
|
|
continue;
|
|
|
|
#include "llvm/IR/Metadata.def"
|
|
|
|
}
|
2015-01-13 06:30:34 +08:00
|
|
|
}
|
2016-03-28 07:59:32 +08:00
|
|
|
writeValueAsMetadata(cast<ValueAsMetadata>(MD), VE, Stream, Record);
|
2010-07-22 07:38:33 +08:00
|
|
|
}
|
2016-03-28 07:53:30 +08:00
|
|
|
}
|
2009-08-04 13:01:35 +08:00
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeModuleMetadata(const Module &M,
|
2016-03-28 07:53:30 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
2016-04-02 23:09:42 +08:00
|
|
|
if (!VE.hasMDs() && M.named_metadata_empty())
|
2016-03-28 07:53:30 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
|
|
|
SmallVector<uint64_t, 64> Record;
|
|
|
|
writeMetadataStrings(VE.getMDStrings(), Stream, Record);
|
|
|
|
writeMetadataRecords(VE.getNonMDStrings(), VE, Stream, Record);
|
2016-03-25 00:16:08 +08:00
|
|
|
writeNamedMetadata(M, VE, Stream, Record);
|
2015-01-13 06:30:34 +08:00
|
|
|
Stream.ExitBlock();
|
2009-09-19 03:26:43 +08:00
|
|
|
}
|
|
|
|
|
2016-03-28 07:56:04 +08:00
|
|
|
static void writeFunctionMetadata(const Function &F, const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
2016-04-02 23:09:42 +08:00
|
|
|
if (!VE.hasMDs())
|
2016-03-28 07:38:36 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
2010-01-14 03:37:33 +08:00
|
|
|
SmallVector<uint64_t, 64> Record;
|
2016-04-02 23:22:57 +08:00
|
|
|
writeMetadataStrings(VE.getMDStrings(), Stream, Record);
|
2016-04-02 23:09:42 +08:00
|
|
|
writeMetadataRecords(VE.getNonMDStrings(), VE, Stream, Record);
|
2016-03-28 07:38:36 +08:00
|
|
|
Stream.ExitBlock();
|
2010-01-14 03:37:33 +08:00
|
|
|
}
|
|
|
|
|
2009-09-19 03:26:43 +08:00
|
|
|
static void WriteMetadataAttachment(const Function &F,
|
2009-09-20 10:20:51 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
2010-04-03 10:17:50 +08:00
|
|
|
Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
|
|
|
|
|
2009-09-19 03:26:43 +08:00
|
|
|
SmallVector<uint64_t, 64> Record;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2009-09-19 03:26:43 +08:00
|
|
|
// Write metadata attachments
|
2011-06-18 01:56:00 +08:00
|
|
|
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
|
2014-11-12 05:30:22 +08:00
|
|
|
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
|
2015-04-25 06:04:41 +08:00
|
|
|
F.getAllMetadata(MDs);
|
|
|
|
if (!MDs.empty()) {
|
|
|
|
for (const auto &I : MDs) {
|
|
|
|
Record.push_back(I.first);
|
|
|
|
Record.push_back(VE.getMetadataID(I.second));
|
|
|
|
}
|
|
|
|
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
|
|
|
|
Record.clear();
|
|
|
|
}
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2015-10-13 11:26:19 +08:00
|
|
|
for (const BasicBlock &BB : F)
|
|
|
|
for (const Instruction &I : BB) {
|
2009-10-23 02:55:16 +08:00
|
|
|
MDs.clear();
|
2015-10-13 11:26:19 +08:00
|
|
|
I.getAllMetadataOtherThanDebugLoc(MDs);
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2009-12-29 07:41:32 +08:00
|
|
|
// If no metadata, ignore instruction.
|
|
|
|
if (MDs.empty()) continue;
|
|
|
|
|
2015-10-13 11:26:19 +08:00
|
|
|
Record.push_back(VE.getInstructionID(&I));
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2009-12-29 07:41:32 +08:00
|
|
|
for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
|
|
|
|
Record.push_back(MDs[i].first);
|
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
|
|
|
Record.push_back(VE.getMetadataID(MDs[i].second));
|
2009-09-19 03:26:43 +08:00
|
|
|
}
|
2011-06-18 01:56:00 +08:00
|
|
|
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
|
2009-12-29 07:41:32 +08:00
|
|
|
Record.clear();
|
2009-09-19 03:26:43 +08:00
|
|
|
}
|
|
|
|
|
2010-04-03 10:17:50 +08:00
|
|
|
Stream.ExitBlock();
|
2009-09-19 03:26:43 +08:00
|
|
|
}
|
|
|
|
|
2009-12-29 04:10:43 +08:00
|
|
|
static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
|
2009-09-19 03:26:43 +08:00
|
|
|
SmallVector<uint64_t, 64> Record;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2009-09-19 03:26:43 +08:00
|
|
|
// Write metadata kinds
|
|
|
|
// METADATA_KIND - [n x [id, name]]
|
2012-12-04 06:57:47 +08:00
|
|
|
SmallVector<StringRef, 8> Names;
|
2009-12-29 17:01:33 +08:00
|
|
|
M->getMDKindNames(Names);
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2010-07-21 05:42:28 +08:00
|
|
|
if (Names.empty()) return;
|
2009-12-29 04:10:43 +08:00
|
|
|
|
2015-11-15 10:00:09 +08:00
|
|
|
Stream.EnterSubblock(bitc::METADATA_KIND_BLOCK_ID, 3);
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2010-07-21 05:42:28 +08:00
|
|
|
for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
|
2009-12-29 04:10:43 +08:00
|
|
|
Record.push_back(MDKindID);
|
|
|
|
StringRef KName = Names[MDKindID];
|
|
|
|
Record.append(KName.begin(), KName.end());
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2009-09-19 03:26:43 +08:00
|
|
|
Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
2009-12-29 04:10:43 +08:00
|
|
|
Stream.ExitBlock();
|
2009-08-04 13:01:35 +08:00
|
|
|
}
|
2009-07-23 01:43:22 +08:00
|
|
|
|
2015-09-25 07:34:52 +08:00
|
|
|
static void WriteOperandBundleTags(const Module *M, BitstreamWriter &Stream) {
|
|
|
|
// Write metadata kinds
|
|
|
|
//
|
|
|
|
// OPERAND_BUNDLE_TAGS_BLOCK_ID : N x OPERAND_BUNDLE_TAG
|
|
|
|
//
|
|
|
|
// OPERAND_BUNDLE_TAG - [strchr x N]
|
|
|
|
|
|
|
|
SmallVector<StringRef, 8> Tags;
|
|
|
|
M->getOperandBundleTags(Tags);
|
|
|
|
|
|
|
|
if (Tags.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
Stream.EnterSubblock(bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID, 3);
|
|
|
|
|
|
|
|
SmallVector<uint64_t, 64> Record;
|
|
|
|
|
|
|
|
for (auto Tag : Tags) {
|
|
|
|
Record.append(Tag.begin(), Tag.end());
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::OPERAND_BUNDLE_TAG, Record, 0);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {
|
|
|
|
if ((int64_t)V >= 0)
|
|
|
|
Vals.push_back(V << 1);
|
|
|
|
else
|
|
|
|
Vals.push_back((-V << 1) | 1);
|
|
|
|
}
|
|
|
|
|
2009-08-04 13:01:35 +08:00
|
|
|
static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream, bool isGlobal) {
|
|
|
|
if (FirstVal == LastVal) return;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2009-08-04 13:01:35 +08:00
|
|
|
Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4);
|
2007-05-06 08:42:18 +08:00
|
|
|
|
2009-08-04 13:01:35 +08:00
|
|
|
unsigned AggregateAbbrev = 0;
|
|
|
|
unsigned String8Abbrev = 0;
|
|
|
|
unsigned CString7Abbrev = 0;
|
|
|
|
unsigned CString6Abbrev = 0;
|
|
|
|
// If this is a constant pool for the module, emit module-specific abbrevs.
|
|
|
|
if (isGlobal) {
|
|
|
|
// Abbrev for CST_CODE_AGGREGATE.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal+1)));
|
|
|
|
AggregateAbbrev = Stream.EmitAbbrev(Abbv);
|
2007-04-24 08:16:04 +08:00
|
|
|
|
2009-08-04 13:01:35 +08:00
|
|
|
// Abbrev for CST_CODE_STRING.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
|
|
|
|
String8Abbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
// Abbrev for CST_CODE_CSTRING.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
|
|
|
|
CString7Abbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
// Abbrev for CST_CODE_CSTRING.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
|
|
|
|
CString6Abbrev = Stream.EmitAbbrev(Abbv);
|
2009-09-20 10:20:51 +08:00
|
|
|
}
|
|
|
|
|
2009-08-04 13:01:35 +08:00
|
|
|
SmallVector<uint64_t, 64> Record;
|
2009-08-04 10:26:56 +08:00
|
|
|
|
2009-08-04 13:01:35 +08:00
|
|
|
const ValueEnumerator::ValueList &Vals = VE.getValues();
|
2014-04-15 14:32:26 +08:00
|
|
|
Type *LastTy = nullptr;
|
2009-08-04 13:01:35 +08:00
|
|
|
for (unsigned i = FirstVal; i != LastVal; ++i) {
|
|
|
|
const Value *V = Vals[i].first;
|
2007-04-24 08:16:04 +08:00
|
|
|
// If we need to switch types, do so now.
|
|
|
|
if (V->getType() != LastTy) {
|
|
|
|
LastTy = V->getType();
|
|
|
|
Record.push_back(VE.getTypeID(LastTy));
|
2007-05-05 15:36:14 +08:00
|
|
|
Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record,
|
|
|
|
CONSTANTS_SETTYPE_ABBREV);
|
2007-04-24 08:16:04 +08:00
|
|
|
Record.clear();
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-24 08:16:04 +08:00
|
|
|
if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
|
2009-10-14 04:46:56 +08:00
|
|
|
Record.push_back(unsigned(IA->hasSideEffects()) |
|
2012-09-05 08:56:20 +08:00
|
|
|
unsigned(IA->isAlignStack()) << 1 |
|
|
|
|
unsigned(IA->getDialect()&1) << 2);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-06 09:58:20 +08:00
|
|
|
// Add the asm string.
|
|
|
|
const std::string &AsmStr = IA->getAsmString();
|
|
|
|
Record.push_back(AsmStr.size());
|
2015-02-17 23:29:18 +08:00
|
|
|
Record.append(AsmStr.begin(), AsmStr.end());
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-06 09:58:20 +08:00
|
|
|
// Add the constraint string.
|
|
|
|
const std::string &ConstraintStr = IA->getConstraintString();
|
|
|
|
Record.push_back(ConstraintStr.size());
|
2015-02-17 23:29:18 +08:00
|
|
|
Record.append(ConstraintStr.begin(), ConstraintStr.end());
|
2007-05-06 09:58:20 +08:00
|
|
|
Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record);
|
|
|
|
Record.clear();
|
2007-04-24 08:16:04 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const Constant *C = cast<Constant>(V);
|
|
|
|
unsigned Code = -1U;
|
|
|
|
unsigned AbbrevToUse = 0;
|
|
|
|
if (C->isNullValue()) {
|
|
|
|
Code = bitc::CST_CODE_NULL;
|
|
|
|
} else if (isa<UndefValue>(C)) {
|
|
|
|
Code = bitc::CST_CODE_UNDEF;
|
|
|
|
} else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
|
Revert patches to add case-range support for PR1255.
The work on this project was left in an unfinished and inconsistent state.
Hopefully someone will eventually get a chance to implement this feature, but
in the meantime, it is better to put things back the way the were. I have
left support in the bitcode reader to handle the case-range bitcode format,
so that we do not lose bitcode compatibility with the llvm 3.3 release.
This reverts the following commits: 155464, 156374, 156377, 156613, 156704,
156757, 156804 156808, 156985, 157046, 157112, 157183, 157315, 157384, 157575,
157576, 157586, 157612, 157810, 157814, 157815, 157880, 157881, 157882, 157884,
157887, 157901, 158979, 157987, 157989, 158986, 158997, 159076, 159101, 159100,
159200, 159201, 159207, 159527, 159532, 159540, 159583, 159618, 159658, 159659,
159660, 159661, 159703, 159704, 160076, 167356, 172025, 186736
llvm-svn: 190328
2013-09-10 03:14:35 +08:00
|
|
|
if (IV->getBitWidth() <= 64) {
|
|
|
|
uint64_t V = IV->getSExtValue();
|
|
|
|
emitSignedInt64(Record, V);
|
|
|
|
Code = bitc::CST_CODE_INTEGER;
|
|
|
|
AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
|
|
|
|
} else { // Wide integers, > 64 bits in size.
|
|
|
|
// We have an arbitrary precision integer value to write whose
|
|
|
|
// bit width is > 64. However, in canonical unsigned integer
|
|
|
|
// format it is likely that the high bits are going to be zero.
|
|
|
|
// So, we only write the number of active words.
|
|
|
|
unsigned NWords = IV->getValue().getActiveWords();
|
|
|
|
const uint64_t *RawWords = IV->getValue().getRawData();
|
|
|
|
for (unsigned i = 0; i != NWords; ++i) {
|
|
|
|
emitSignedInt64(Record, RawWords[i]);
|
|
|
|
}
|
|
|
|
Code = bitc::CST_CODE_WIDE_INTEGER;
|
|
|
|
}
|
2007-04-24 08:16:04 +08:00
|
|
|
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
|
|
|
|
Code = bitc::CST_CODE_FLOAT;
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty = CFP->getType();
|
2011-12-17 08:04:22 +08:00
|
|
|
if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) {
|
2008-10-10 02:53:47 +08:00
|
|
|
Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
|
2009-10-05 13:54:46 +08:00
|
|
|
} else if (Ty->isX86_FP80Ty()) {
|
2007-09-27 07:20:33 +08:00
|
|
|
// api needed to prevent premature destruction
|
2009-03-24 05:16:53 +08:00
|
|
|
// bits are not in the same order as a normal i80 APInt, compensate.
|
2008-10-10 02:53:47 +08:00
|
|
|
APInt api = CFP->getValueAPF().bitcastToAPInt();
|
2007-09-27 07:20:33 +08:00
|
|
|
const uint64_t *p = api.getRawData();
|
2009-03-24 05:16:53 +08:00
|
|
|
Record.push_back((p[1] << 48) | (p[0] >> 16));
|
|
|
|
Record.push_back(p[0] & 0xffffLL);
|
2009-10-05 13:54:46 +08:00
|
|
|
} else if (Ty->isFP128Ty() || Ty->isPPC_FP128Ty()) {
|
2008-10-10 02:53:47 +08:00
|
|
|
APInt api = CFP->getValueAPF().bitcastToAPInt();
|
2007-09-27 07:20:33 +08:00
|
|
|
const uint64_t *p = api.getRawData();
|
2007-09-12 02:32:33 +08:00
|
|
|
Record.push_back(p[0]);
|
|
|
|
Record.push_back(p[1]);
|
2007-08-10 06:51:36 +08:00
|
|
|
} else {
|
|
|
|
assert (0 && "Unknown FP type!");
|
2007-04-24 08:16:04 +08:00
|
|
|
}
|
2012-01-30 08:51:16 +08:00
|
|
|
} else if (isa<ConstantDataSequential>(C) &&
|
|
|
|
cast<ConstantDataSequential>(C)->isString()) {
|
|
|
|
const ConstantDataSequential *Str = cast<ConstantDataSequential>(C);
|
|
|
|
// Emit constant strings specially.
|
|
|
|
unsigned NumElts = Str->getNumElements();
|
|
|
|
// If this is a null-terminated string, use the denser CSTRING encoding.
|
|
|
|
if (Str->isCString()) {
|
|
|
|
Code = bitc::CST_CODE_CSTRING;
|
|
|
|
--NumElts; // Don't encode the null, which isn't allowed by char6.
|
|
|
|
} else {
|
|
|
|
Code = bitc::CST_CODE_STRING;
|
|
|
|
AbbrevToUse = String8Abbrev;
|
|
|
|
}
|
|
|
|
bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
|
|
|
|
bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
|
|
|
|
for (unsigned i = 0; i != NumElts; ++i) {
|
|
|
|
unsigned char V = Str->getElementAsInteger(i);
|
|
|
|
Record.push_back(V);
|
|
|
|
isCStr7 &= (V & 128) == 0;
|
|
|
|
if (isCStrChar6)
|
|
|
|
isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
|
|
|
|
}
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2012-01-30 08:51:16 +08:00
|
|
|
if (isCStrChar6)
|
|
|
|
AbbrevToUse = CString6Abbrev;
|
|
|
|
else if (isCStr7)
|
|
|
|
AbbrevToUse = CString7Abbrev;
|
2012-11-16 06:34:00 +08:00
|
|
|
} else if (const ConstantDataSequential *CDS =
|
2012-01-30 08:51:16 +08:00
|
|
|
dyn_cast<ConstantDataSequential>(C)) {
|
2012-01-30 15:36:01 +08:00
|
|
|
Code = bitc::CST_CODE_DATA;
|
2012-01-30 08:51:16 +08:00
|
|
|
Type *EltTy = CDS->getType()->getElementType();
|
|
|
|
if (isa<IntegerType>(EltTy)) {
|
|
|
|
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
|
|
|
|
Record.push_back(CDS->getElementAsInteger(i));
|
|
|
|
} else {
|
2016-01-07 06:31:32 +08:00
|
|
|
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
|
|
|
|
Record.push_back(
|
|
|
|
CDS->getElementAsAPFloat(i).bitcastToAPInt().getLimitedValue());
|
2012-01-30 08:51:16 +08:00
|
|
|
}
|
2016-04-06 05:10:45 +08:00
|
|
|
} else if (isa<ConstantAggregate>(C)) {
|
2007-04-24 08:16:04 +08:00
|
|
|
Code = bitc::CST_CODE_AGGREGATE;
|
2015-06-26 04:51:38 +08:00
|
|
|
for (const Value *Op : C->operands())
|
|
|
|
Record.push_back(VE.getValueID(Op));
|
2007-05-05 15:36:14 +08:00
|
|
|
AbbrevToUse = AggregateAbbrev;
|
2007-04-24 08:16:04 +08:00
|
|
|
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
|
2007-04-24 15:07:11 +08:00
|
|
|
switch (CE->getOpcode()) {
|
|
|
|
default:
|
|
|
|
if (Instruction::isCast(CE->getOpcode())) {
|
|
|
|
Code = bitc::CST_CODE_CE_CAST;
|
|
|
|
Record.push_back(GetEncodedCastOpcode(CE->getOpcode()));
|
|
|
|
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
2007-05-05 15:36:14 +08:00
|
|
|
AbbrevToUse = CONSTANTS_CE_CAST_Abbrev;
|
2007-04-24 15:07:11 +08:00
|
|
|
} else {
|
|
|
|
assert(CE->getNumOperands() == 2 && "Unknown constant expr!");
|
|
|
|
Code = bitc::CST_CODE_CE_BINOP;
|
|
|
|
Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode()));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(1)));
|
2009-07-21 05:19:07 +08:00
|
|
|
uint64_t Flags = GetOptimizationFlags(CE);
|
|
|
|
if (Flags != 0)
|
|
|
|
Record.push_back(Flags);
|
2007-04-24 15:07:11 +08:00
|
|
|
}
|
|
|
|
break;
|
2015-03-14 05:03:36 +08:00
|
|
|
case Instruction::GetElementPtr: {
|
2007-04-24 15:07:11 +08:00
|
|
|
Code = bitc::CST_CODE_CE_GEP;
|
2015-03-14 05:03:36 +08:00
|
|
|
const auto *GO = cast<GEPOperator>(C);
|
|
|
|
if (GO->isInBounds())
|
2009-07-28 05:53:46 +08:00
|
|
|
Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
|
2015-03-14 05:03:36 +08:00
|
|
|
Record.push_back(VE.getTypeID(GO->getSourceElementType()));
|
2007-04-24 15:07:11 +08:00
|
|
|
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
|
|
|
|
Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(i)));
|
|
|
|
}
|
|
|
|
break;
|
2015-03-14 05:03:36 +08:00
|
|
|
}
|
2007-04-24 15:07:11 +08:00
|
|
|
case Instruction::Select:
|
|
|
|
Code = bitc::CST_CODE_CE_SELECT;
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(1)));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(2)));
|
|
|
|
break;
|
|
|
|
case Instruction::ExtractElement:
|
|
|
|
Code = bitc::CST_CODE_CE_EXTRACTELT;
|
|
|
|
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
[IR] Make {extract,insert}element accept an index of any integer type.
Given the following C code llvm currently generates suboptimal code for
x86-64:
__m128 bss4( const __m128 *ptr, size_t i, size_t j )
{
float f = ptr[i][j];
return (__m128) { f, f, f, f };
}
=================================================
define <4 x float> @_Z4bss4PKDv4_fmm(<4 x float>* nocapture readonly %ptr, i64 %i, i64 %j) #0 {
%a1 = getelementptr inbounds <4 x float>* %ptr, i64 %i
%a2 = load <4 x float>* %a1, align 16, !tbaa !1
%a3 = trunc i64 %j to i32
%a4 = extractelement <4 x float> %a2, i32 %a3
%a5 = insertelement <4 x float> undef, float %a4, i32 0
%a6 = insertelement <4 x float> %a5, float %a4, i32 1
%a7 = insertelement <4 x float> %a6, float %a4, i32 2
%a8 = insertelement <4 x float> %a7, float %a4, i32 3
ret <4 x float> %a8
}
=================================================
shlq $4, %rsi
addq %rdi, %rsi
movslq %edx, %rax
vbroadcastss (%rsi,%rax,4), %xmm0
retq
=================================================
The movslq is uneeded, but is present because of the trunc to i32 and then
sext back to i64 that the backend adds for vbroadcastss.
We can't remove it because it changes the meaning. The IR that clang
generates is already suboptimal. What clang really should emit is:
%a4 = extractelement <4 x float> %a2, i64 %j
This patch makes that legal. A separate patch will teach clang to do it.
Differential Revision: http://reviews.llvm.org/D3519
llvm-svn: 207801
2014-05-02 06:12:39 +08:00
|
|
|
Record.push_back(VE.getTypeID(C->getOperand(1)->getType()));
|
2007-04-24 15:07:11 +08:00
|
|
|
Record.push_back(VE.getValueID(C->getOperand(1)));
|
|
|
|
break;
|
|
|
|
case Instruction::InsertElement:
|
|
|
|
Code = bitc::CST_CODE_CE_INSERTELT;
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(1)));
|
[IR] Make {extract,insert}element accept an index of any integer type.
Given the following C code llvm currently generates suboptimal code for
x86-64:
__m128 bss4( const __m128 *ptr, size_t i, size_t j )
{
float f = ptr[i][j];
return (__m128) { f, f, f, f };
}
=================================================
define <4 x float> @_Z4bss4PKDv4_fmm(<4 x float>* nocapture readonly %ptr, i64 %i, i64 %j) #0 {
%a1 = getelementptr inbounds <4 x float>* %ptr, i64 %i
%a2 = load <4 x float>* %a1, align 16, !tbaa !1
%a3 = trunc i64 %j to i32
%a4 = extractelement <4 x float> %a2, i32 %a3
%a5 = insertelement <4 x float> undef, float %a4, i32 0
%a6 = insertelement <4 x float> %a5, float %a4, i32 1
%a7 = insertelement <4 x float> %a6, float %a4, i32 2
%a8 = insertelement <4 x float> %a7, float %a4, i32 3
ret <4 x float> %a8
}
=================================================
shlq $4, %rsi
addq %rdi, %rsi
movslq %edx, %rax
vbroadcastss (%rsi,%rax,4), %xmm0
retq
=================================================
The movslq is uneeded, but is present because of the trunc to i32 and then
sext back to i64 that the backend adds for vbroadcastss.
We can't remove it because it changes the meaning. The IR that clang
generates is already suboptimal. What clang really should emit is:
%a4 = extractelement <4 x float> %a2, i64 %j
This patch makes that legal. A separate patch will teach clang to do it.
Differential Revision: http://reviews.llvm.org/D3519
llvm-svn: 207801
2014-05-02 06:12:39 +08:00
|
|
|
Record.push_back(VE.getTypeID(C->getOperand(2)->getType()));
|
2007-04-24 15:07:11 +08:00
|
|
|
Record.push_back(VE.getValueID(C->getOperand(2)));
|
|
|
|
break;
|
|
|
|
case Instruction::ShuffleVector:
|
2009-02-13 05:28:33 +08:00
|
|
|
// If the return type and argument types are the same, this is a
|
|
|
|
// standard shufflevector instruction. If the types are different,
|
|
|
|
// then the shuffle is widening or truncating the input vectors, and
|
|
|
|
// the argument type must also be encoded.
|
|
|
|
if (C->getType() == C->getOperand(0)->getType()) {
|
|
|
|
Code = bitc::CST_CODE_CE_SHUFFLEVEC;
|
|
|
|
} else {
|
|
|
|
Code = bitc::CST_CODE_CE_SHUFVEC_EX;
|
|
|
|
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
|
|
|
|
}
|
2007-04-24 15:07:11 +08:00
|
|
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(1)));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(2)));
|
|
|
|
break;
|
|
|
|
case Instruction::ICmp:
|
|
|
|
case Instruction::FCmp:
|
2009-07-08 11:04:38 +08:00
|
|
|
Code = bitc::CST_CODE_CE_CMP;
|
2007-04-24 15:07:11 +08:00
|
|
|
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
|
|
|
Record.push_back(VE.getValueID(C->getOperand(1)));
|
|
|
|
Record.push_back(CE->getPredicate());
|
|
|
|
break;
|
|
|
|
}
|
2009-10-28 13:24:40 +08:00
|
|
|
} else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
|
|
|
|
Code = bitc::CST_CODE_BLOCKADDRESS;
|
|
|
|
Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
|
|
|
|
Record.push_back(VE.getValueID(BA->getFunction()));
|
|
|
|
Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
|
2007-04-24 08:16:04 +08:00
|
|
|
} else {
|
2010-07-22 05:18:37 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
C->dump();
|
|
|
|
#endif
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unknown constant!");
|
2007-04-24 08:16:04 +08:00
|
|
|
}
|
|
|
|
Stream.EmitRecord(Code, Record, AbbrevToUse);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WriteModuleConstants(const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
|
|
|
const ValueEnumerator::ValueList &Vals = VE.getValues();
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-24 08:16:04 +08:00
|
|
|
// Find the first constant to emit, which is the first non-globalvalue value.
|
|
|
|
// We know globalvalues have been emitted by WriteModuleInfo.
|
|
|
|
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
|
|
|
|
if (!isa<GlobalValue>(Vals[i].first)) {
|
2009-08-04 13:01:35 +08:00
|
|
|
WriteConstants(i, Vals.size(), VE, Stream, true);
|
2007-04-24 08:16:04 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-04-24 04:35:01 +08:00
|
|
|
|
2007-05-06 08:00:00 +08:00
|
|
|
/// PushValueAndType - The file has to encode both the value and type id for
|
|
|
|
/// many values, because we need to know what type to create for forward
|
|
|
|
/// references. However, most operands are not forward references, so this type
|
|
|
|
/// field is not needed.
|
|
|
|
///
|
|
|
|
/// This function adds V's value ID to Vals. If the value ID is higher than the
|
|
|
|
/// instruction ID, then it is a forward reference, and it also includes the
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
/// type ID. The value ID that is written is encoded relative to the InstID.
|
2009-01-17 02:40:27 +08:00
|
|
|
static bool PushValueAndType(const Value *V, unsigned InstID,
|
2013-07-12 00:22:38 +08:00
|
|
|
SmallVectorImpl<unsigned> &Vals,
|
2007-05-06 08:00:00 +08:00
|
|
|
ValueEnumerator &VE) {
|
|
|
|
unsigned ValID = VE.getValueID(V);
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
// Make encoding relative to the InstID.
|
|
|
|
Vals.push_back(InstID - ValID);
|
2007-05-06 08:00:00 +08:00
|
|
|
if (ValID >= InstID) {
|
|
|
|
Vals.push_back(VE.getTypeID(V->getType()));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-09-25 07:34:52 +08:00
|
|
|
static void WriteOperandBundles(BitstreamWriter &Stream, ImmutableCallSite CS,
|
|
|
|
unsigned InstID, ValueEnumerator &VE) {
|
|
|
|
SmallVector<unsigned, 64> Record;
|
|
|
|
LLVMContext &C = CS.getInstruction()->getContext();
|
|
|
|
|
|
|
|
for (unsigned i = 0, e = CS.getNumOperandBundles(); i != e; ++i) {
|
2015-11-07 09:56:04 +08:00
|
|
|
const auto &Bundle = CS.getOperandBundleAt(i);
|
2015-11-11 04:13:15 +08:00
|
|
|
Record.push_back(C.getOperandBundleTagID(Bundle.getTagName()));
|
2015-09-25 07:34:52 +08:00
|
|
|
|
|
|
|
for (auto &Input : Bundle.Inputs)
|
|
|
|
PushValueAndType(Input, InstID, Record, VE);
|
|
|
|
|
|
|
|
Stream.EmitRecord(bitc::FUNC_CODE_OPERAND_BUNDLE, Record);
|
|
|
|
Record.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
/// pushValue - Like PushValueAndType, but where the type of the value is
|
|
|
|
/// omitted (perhaps it was already encoded in an earlier operand).
|
|
|
|
static void pushValue(const Value *V, unsigned InstID,
|
2013-07-12 00:22:38 +08:00
|
|
|
SmallVectorImpl<unsigned> &Vals,
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
ValueEnumerator &VE) {
|
|
|
|
unsigned ValID = VE.getValueID(V);
|
|
|
|
Vals.push_back(InstID - ValID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pushValueSigned(const Value *V, unsigned InstID,
|
2013-07-12 00:22:38 +08:00
|
|
|
SmallVectorImpl<uint64_t> &Vals,
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
ValueEnumerator &VE) {
|
|
|
|
unsigned ValID = VE.getValueID(V);
|
|
|
|
int64_t diff = ((int32_t)InstID - (int32_t)ValID);
|
|
|
|
emitSignedInt64(Vals, diff);
|
|
|
|
}
|
|
|
|
|
2007-04-26 13:53:54 +08:00
|
|
|
/// WriteInstruction - Emit an instruction to the specified stream.
|
2007-05-06 08:00:00 +08:00
|
|
|
static void WriteInstruction(const Instruction &I, unsigned InstID,
|
|
|
|
ValueEnumerator &VE, BitstreamWriter &Stream,
|
2013-07-12 00:22:38 +08:00
|
|
|
SmallVectorImpl<unsigned> &Vals) {
|
2007-04-26 13:53:54 +08:00
|
|
|
unsigned Code = 0;
|
|
|
|
unsigned AbbrevToUse = 0;
|
2009-09-19 03:26:43 +08:00
|
|
|
VE.setInstructionID(&I);
|
2007-04-26 13:53:54 +08:00
|
|
|
switch (I.getOpcode()) {
|
|
|
|
default:
|
|
|
|
if (Instruction::isCast(I.getOpcode())) {
|
2007-05-01 10:13:26 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_CAST;
|
2007-05-06 10:38:57 +08:00
|
|
|
if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
|
|
|
|
AbbrevToUse = FUNCTION_INST_CAST_ABBREV;
|
2007-04-26 13:53:54 +08:00
|
|
|
Vals.push_back(VE.getTypeID(I.getType()));
|
2007-05-06 08:21:25 +08:00
|
|
|
Vals.push_back(GetEncodedCastOpcode(I.getOpcode()));
|
2007-04-26 13:53:54 +08:00
|
|
|
} else {
|
|
|
|
assert(isa<BinaryOperator>(I) && "Unknown instruction!");
|
2007-05-02 12:26:36 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_BINOP;
|
2007-05-06 10:38:57 +08:00
|
|
|
if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
|
|
|
|
AbbrevToUse = FUNCTION_INST_BINOP_ABBREV;
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(1), InstID, Vals, VE);
|
2007-05-06 08:21:25 +08:00
|
|
|
Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
|
2009-07-21 05:19:07 +08:00
|
|
|
uint64_t Flags = GetOptimizationFlags(&I);
|
|
|
|
if (Flags != 0) {
|
|
|
|
if (AbbrevToUse == FUNCTION_INST_BINOP_ABBREV)
|
|
|
|
AbbrevToUse = FUNCTION_INST_BINOP_FLAGS_ABBREV;
|
|
|
|
Vals.push_back(Flags);
|
|
|
|
}
|
2007-04-26 13:53:54 +08:00
|
|
|
}
|
|
|
|
break;
|
2007-05-01 10:13:26 +08:00
|
|
|
|
2015-02-25 09:08:52 +08:00
|
|
|
case Instruction::GetElementPtr: {
|
2007-05-01 10:13:26 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_GEP;
|
2015-02-25 09:08:52 +08:00
|
|
|
AbbrevToUse = FUNCTION_INST_GEP_ABBREV;
|
|
|
|
auto &GEPInst = cast<GetElementPtrInst>(I);
|
|
|
|
Vals.push_back(GEPInst.isInBounds());
|
|
|
|
Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType()));
|
2007-05-06 08:00:00 +08:00
|
|
|
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
|
|
|
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
2015-02-25 09:08:52 +08:00
|
|
|
}
|
2008-06-01 03:11:15 +08:00
|
|
|
case Instruction::ExtractValue: {
|
2008-05-23 09:55:30 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_EXTRACTVAL;
|
2008-06-01 03:11:15 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
|
|
|
const ExtractValueInst *EVI = cast<ExtractValueInst>(&I);
|
2015-02-17 23:29:18 +08:00
|
|
|
Vals.append(EVI->idx_begin(), EVI->idx_end());
|
2008-05-23 09:55:30 +08:00
|
|
|
break;
|
2008-06-01 03:11:15 +08:00
|
|
|
}
|
|
|
|
case Instruction::InsertValue: {
|
2008-05-23 09:55:30 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_INSERTVAL;
|
2008-06-01 03:11:15 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
|
|
|
PushValueAndType(I.getOperand(1), InstID, Vals, VE);
|
|
|
|
const InsertValueInst *IVI = cast<InsertValueInst>(&I);
|
2015-02-17 23:29:18 +08:00
|
|
|
Vals.append(IVI->idx_begin(), IVI->idx_end());
|
2008-05-23 09:55:30 +08:00
|
|
|
break;
|
2008-06-01 03:11:15 +08:00
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
case Instruction::Select:
|
2008-09-16 09:01:33 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_VSELECT;
|
2007-05-06 08:21:25 +08:00
|
|
|
PushValueAndType(I.getOperand(1), InstID, Vals, VE);
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(2), InstID, Vals, VE);
|
2008-09-16 09:01:33 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
|
|
|
case Instruction::ExtractElement:
|
|
|
|
Code = bitc::FUNC_CODE_INST_EXTRACTELT;
|
2007-05-06 08:21:25 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
[IR] Make {extract,insert}element accept an index of any integer type.
Given the following C code llvm currently generates suboptimal code for
x86-64:
__m128 bss4( const __m128 *ptr, size_t i, size_t j )
{
float f = ptr[i][j];
return (__m128) { f, f, f, f };
}
=================================================
define <4 x float> @_Z4bss4PKDv4_fmm(<4 x float>* nocapture readonly %ptr, i64 %i, i64 %j) #0 {
%a1 = getelementptr inbounds <4 x float>* %ptr, i64 %i
%a2 = load <4 x float>* %a1, align 16, !tbaa !1
%a3 = trunc i64 %j to i32
%a4 = extractelement <4 x float> %a2, i32 %a3
%a5 = insertelement <4 x float> undef, float %a4, i32 0
%a6 = insertelement <4 x float> %a5, float %a4, i32 1
%a7 = insertelement <4 x float> %a6, float %a4, i32 2
%a8 = insertelement <4 x float> %a7, float %a4, i32 3
ret <4 x float> %a8
}
=================================================
shlq $4, %rsi
addq %rdi, %rsi
movslq %edx, %rax
vbroadcastss (%rsi,%rax,4), %xmm0
retq
=================================================
The movslq is uneeded, but is present because of the trunc to i32 and then
sext back to i64 that the backend adds for vbroadcastss.
We can't remove it because it changes the meaning. The IR that clang
generates is already suboptimal. What clang really should emit is:
%a4 = extractelement <4 x float> %a2, i64 %j
This patch makes that legal. A separate patch will teach clang to do it.
Differential Revision: http://reviews.llvm.org/D3519
llvm-svn: 207801
2014-05-02 06:12:39 +08:00
|
|
|
PushValueAndType(I.getOperand(1), InstID, Vals, VE);
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
|
|
|
case Instruction::InsertElement:
|
|
|
|
Code = bitc::FUNC_CODE_INST_INSERTELT;
|
2007-05-06 08:21:25 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(1), InstID, Vals, VE);
|
[IR] Make {extract,insert}element accept an index of any integer type.
Given the following C code llvm currently generates suboptimal code for
x86-64:
__m128 bss4( const __m128 *ptr, size_t i, size_t j )
{
float f = ptr[i][j];
return (__m128) { f, f, f, f };
}
=================================================
define <4 x float> @_Z4bss4PKDv4_fmm(<4 x float>* nocapture readonly %ptr, i64 %i, i64 %j) #0 {
%a1 = getelementptr inbounds <4 x float>* %ptr, i64 %i
%a2 = load <4 x float>* %a1, align 16, !tbaa !1
%a3 = trunc i64 %j to i32
%a4 = extractelement <4 x float> %a2, i32 %a3
%a5 = insertelement <4 x float> undef, float %a4, i32 0
%a6 = insertelement <4 x float> %a5, float %a4, i32 1
%a7 = insertelement <4 x float> %a6, float %a4, i32 2
%a8 = insertelement <4 x float> %a7, float %a4, i32 3
ret <4 x float> %a8
}
=================================================
shlq $4, %rsi
addq %rdi, %rsi
movslq %edx, %rax
vbroadcastss (%rsi,%rax,4), %xmm0
retq
=================================================
The movslq is uneeded, but is present because of the trunc to i32 and then
sext back to i64 that the backend adds for vbroadcastss.
We can't remove it because it changes the meaning. The IR that clang
generates is already suboptimal. What clang really should emit is:
%a4 = extractelement <4 x float> %a2, i64 %j
This patch makes that legal. A separate patch will teach clang to do it.
Differential Revision: http://reviews.llvm.org/D3519
llvm-svn: 207801
2014-05-02 06:12:39 +08:00
|
|
|
PushValueAndType(I.getOperand(2), InstID, Vals, VE);
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
|
|
|
case Instruction::ShuffleVector:
|
|
|
|
Code = bitc::FUNC_CODE_INST_SHUFFLEVEC;
|
2007-05-06 08:21:25 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(1), InstID, Vals, VE);
|
|
|
|
pushValue(I.getOperand(2), InstID, Vals, VE);
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
|
|
|
case Instruction::ICmp:
|
2015-07-10 20:52:00 +08:00
|
|
|
case Instruction::FCmp: {
|
2009-07-08 11:04:38 +08:00
|
|
|
// compare returning Int1Ty or vector of Int1Ty
|
|
|
|
Code = bitc::FUNC_CODE_INST_CMP2;
|
2007-05-06 08:00:00 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(1), InstID, Vals, VE);
|
2007-05-01 10:13:26 +08:00
|
|
|
Vals.push_back(cast<CmpInst>(I).getPredicate());
|
2015-07-10 20:52:00 +08:00
|
|
|
uint64_t Flags = GetOptimizationFlags(&I);
|
|
|
|
if (Flags != 0)
|
|
|
|
Vals.push_back(Flags);
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
2015-07-10 20:52:00 +08:00
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
|
2009-09-20 10:20:51 +08:00
|
|
|
case Instruction::Ret:
|
2008-02-26 09:29:32 +08:00
|
|
|
{
|
|
|
|
Code = bitc::FUNC_CODE_INST_RET;
|
|
|
|
unsigned NumOperands = I.getNumOperands();
|
|
|
|
if (NumOperands == 0)
|
|
|
|
AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV;
|
|
|
|
else if (NumOperands == 1) {
|
|
|
|
if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
|
|
|
|
AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV;
|
|
|
|
} else {
|
|
|
|
for (unsigned i = 0, e = NumOperands; i != e; ++i)
|
|
|
|
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
|
|
|
|
}
|
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
|
|
|
case Instruction::Br:
|
2009-01-31 02:27:21 +08:00
|
|
|
{
|
|
|
|
Code = bitc::FUNC_CODE_INST_BR;
|
2013-02-11 09:16:51 +08:00
|
|
|
const BranchInst &II = cast<BranchInst>(I);
|
2009-01-31 02:27:21 +08:00
|
|
|
Vals.push_back(VE.getValueID(II.getSuccessor(0)));
|
|
|
|
if (II.isConditional()) {
|
|
|
|
Vals.push_back(VE.getValueID(II.getSuccessor(1)));
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(II.getCondition(), InstID, Vals, VE);
|
2009-01-31 02:27:21 +08:00
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Instruction::Switch:
|
SwitchInst refactoring.
The purpose of refactoring is to hide operand roles from SwitchInst user (programmer). If you want to play with operands directly, probably you will need lower level methods than SwitchInst ones (TerminatorInst or may be User). After this patch we can reorganize SwitchInst operands and successors as we want.
What was done:
1. Changed semantics of index inside the getCaseValue method:
getCaseValue(0) means "get first case", not a condition. Use getCondition() if you want to resolve the condition. I propose don't mix SwitchInst case indexing with low level indexing (TI successors indexing, User's operands indexing), since it may be dangerous.
2. By the same reason findCaseValue(ConstantInt*) returns actual number of case value. 0 means first case, not default. If there is no case with given value, ErrorIndex will returned.
3. Added getCaseSuccessor method. I propose to avoid usage of TerminatorInst::getSuccessor if you want to resolve case successor BB. Use getCaseSuccessor instead, since internal SwitchInst organization of operands/successors is hidden and may be changed in any moment.
4. Added resolveSuccessorIndex and resolveCaseIndex. The main purpose of these methods is to see how case successors are really mapped in TerminatorInst.
4.1 "resolveSuccessorIndex" was created if you need to level down from SwitchInst to TerminatorInst. It returns TerminatorInst's successor index for given case successor.
4.2 "resolveCaseIndex" converts low level successors index to case index that curresponds to the given successor.
Note: There are also related compatability fix patches for dragonegg, klee, llvm-gcc-4.0, llvm-gcc-4.2, safecode, clang.
llvm-svn: 149481
2012-02-01 15:49:51 +08:00
|
|
|
{
|
|
|
|
Code = bitc::FUNC_CODE_INST_SWITCH;
|
2013-02-11 09:16:51 +08:00
|
|
|
const SwitchInst &SI = cast<SwitchInst>(I);
|
Revert patches to add case-range support for PR1255.
The work on this project was left in an unfinished and inconsistent state.
Hopefully someone will eventually get a chance to implement this feature, but
in the meantime, it is better to put things back the way the were. I have
left support in the bitcode reader to handle the case-range bitcode format,
so that we do not lose bitcode compatibility with the llvm 3.3 release.
This reverts the following commits: 155464, 156374, 156377, 156613, 156704,
156757, 156804 156808, 156985, 157046, 157112, 157183, 157315, 157384, 157575,
157576, 157586, 157612, 157810, 157814, 157815, 157880, 157881, 157882, 157884,
157887, 157901, 158979, 157987, 157989, 158986, 158997, 159076, 159101, 159100,
159200, 159201, 159207, 159527, 159532, 159540, 159583, 159618, 159658, 159659,
159660, 159661, 159703, 159704, 160076, 167356, 172025, 186736
llvm-svn: 190328
2013-09-10 03:14:35 +08:00
|
|
|
Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
|
|
|
|
pushValue(SI.getCondition(), InstID, Vals, VE);
|
|
|
|
Vals.push_back(VE.getValueID(SI.getDefaultDest()));
|
2015-11-14 00:21:23 +08:00
|
|
|
for (SwitchInst::ConstCaseIt Case : SI.cases()) {
|
|
|
|
Vals.push_back(VE.getValueID(Case.getCaseValue()));
|
|
|
|
Vals.push_back(VE.getValueID(Case.getCaseSuccessor()));
|
SwitchInst refactoring.
The purpose of refactoring is to hide operand roles from SwitchInst user (programmer). If you want to play with operands directly, probably you will need lower level methods than SwitchInst ones (TerminatorInst or may be User). After this patch we can reorganize SwitchInst operands and successors as we want.
What was done:
1. Changed semantics of index inside the getCaseValue method:
getCaseValue(0) means "get first case", not a condition. Use getCondition() if you want to resolve the condition. I propose don't mix SwitchInst case indexing with low level indexing (TI successors indexing, User's operands indexing), since it may be dangerous.
2. By the same reason findCaseValue(ConstantInt*) returns actual number of case value. 0 means first case, not default. If there is no case with given value, ErrorIndex will returned.
3. Added getCaseSuccessor method. I propose to avoid usage of TerminatorInst::getSuccessor if you want to resolve case successor BB. Use getCaseSuccessor instead, since internal SwitchInst organization of operands/successors is hidden and may be changed in any moment.
4. Added resolveSuccessorIndex and resolveCaseIndex. The main purpose of these methods is to see how case successors are really mapped in TerminatorInst.
4.1 "resolveSuccessorIndex" was created if you need to level down from SwitchInst to TerminatorInst. It returns TerminatorInst's successor index for given case successor.
4.2 "resolveCaseIndex" converts low level successors index to case index that curresponds to the given successor.
Note: There are also related compatability fix patches for dragonegg, klee, llvm-gcc-4.0, llvm-gcc-4.2, safecode, clang.
llvm-svn: 149481
2012-02-01 15:49:51 +08:00
|
|
|
}
|
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
2009-10-28 08:19:10 +08:00
|
|
|
case Instruction::IndirectBr:
|
|
|
|
Code = bitc::FUNC_CODE_INST_INDIRECTBR;
|
2009-10-28 03:13:16 +08:00
|
|
|
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
// Encode the address operand as relative, but not the basic blocks.
|
|
|
|
pushValue(I.getOperand(0), InstID, Vals, VE);
|
|
|
|
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
|
2009-10-28 03:13:16 +08:00
|
|
|
Vals.push_back(VE.getValueID(I.getOperand(i)));
|
|
|
|
break;
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2007-05-01 15:03:37 +08:00
|
|
|
case Instruction::Invoke: {
|
2009-01-17 02:40:27 +08:00
|
|
|
const InvokeInst *II = cast<InvokeInst>(&I);
|
2015-04-25 02:06:06 +08:00
|
|
|
const Value *Callee = II->getCalledValue();
|
|
|
|
FunctionType *FTy = II->getFunctionType();
|
2015-09-25 07:34:52 +08:00
|
|
|
|
|
|
|
if (II->hasOperandBundles())
|
|
|
|
WriteOperandBundles(Stream, II, InstID, VE);
|
|
|
|
|
2007-05-01 10:13:26 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_INVOKE;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2008-09-26 05:00:45 +08:00
|
|
|
Vals.push_back(VE.getAttributeID(II->getAttributes()));
|
2015-04-25 02:06:06 +08:00
|
|
|
Vals.push_back(II->getCallingConv() | 1 << 13);
|
2009-01-08 06:39:29 +08:00
|
|
|
Vals.push_back(VE.getValueID(II->getNormalDest()));
|
|
|
|
Vals.push_back(VE.getValueID(II->getUnwindDest()));
|
2015-04-25 02:06:06 +08:00
|
|
|
Vals.push_back(VE.getTypeID(FTy));
|
2009-01-17 02:40:27 +08:00
|
|
|
PushValueAndType(Callee, InstID, Vals, VE);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-01 10:13:26 +08:00
|
|
|
// Emit value #'s for the fixed parameters.
|
|
|
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(i), InstID, Vals, VE); // fixed param.
|
2007-05-01 10:13:26 +08:00
|
|
|
|
|
|
|
// Emit type/value pairs for varargs params.
|
|
|
|
if (FTy->isVarArg()) {
|
2010-03-24 21:21:49 +08:00
|
|
|
for (unsigned i = FTy->getNumParams(), e = I.getNumOperands()-3;
|
2007-05-06 08:00:00 +08:00
|
|
|
i != e; ++i)
|
|
|
|
PushValueAndType(I.getOperand(i), InstID, Vals, VE); // vararg
|
2007-05-01 10:13:26 +08:00
|
|
|
}
|
|
|
|
break;
|
2007-05-01 15:03:37 +08:00
|
|
|
}
|
2011-07-31 14:30:59 +08:00
|
|
|
case Instruction::Resume:
|
|
|
|
Code = bitc::FUNC_CODE_INST_RESUME;
|
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
|
|
|
break;
|
2015-08-01 01:58:14 +08:00
|
|
|
case Instruction::CleanupRet: {
|
|
|
|
Code = bitc::FUNC_CODE_INST_CLEANUPRET;
|
|
|
|
const auto &CRI = cast<CleanupReturnInst>(I);
|
2015-08-23 08:26:33 +08:00
|
|
|
pushValue(CRI.getCleanupPad(), InstID, Vals, VE);
|
2015-08-01 01:58:14 +08:00
|
|
|
if (CRI.hasUnwindDest())
|
|
|
|
Vals.push_back(VE.getValueID(CRI.getUnwindDest()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::CatchRet: {
|
|
|
|
Code = bitc::FUNC_CODE_INST_CATCHRET;
|
|
|
|
const auto &CRI = cast<CatchReturnInst>(I);
|
2015-08-23 08:26:33 +08:00
|
|
|
pushValue(CRI.getCatchPad(), InstID, Vals, VE);
|
2015-08-01 01:58:14 +08:00
|
|
|
Vals.push_back(VE.getValueID(CRI.getSuccessor()));
|
|
|
|
break;
|
|
|
|
}
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
case Instruction::CleanupPad:
|
2015-08-01 01:58:14 +08:00
|
|
|
case Instruction::CatchPad: {
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
const auto &FuncletPad = cast<FuncletPadInst>(I);
|
|
|
|
Code = isa<CatchPadInst>(FuncletPad) ? bitc::FUNC_CODE_INST_CATCHPAD
|
|
|
|
: bitc::FUNC_CODE_INST_CLEANUPPAD;
|
|
|
|
pushValue(FuncletPad.getParentPad(), InstID, Vals, VE);
|
|
|
|
|
|
|
|
unsigned NumArgOperands = FuncletPad.getNumArgOperands();
|
2015-08-01 01:58:14 +08:00
|
|
|
Vals.push_back(NumArgOperands);
|
|
|
|
for (unsigned Op = 0; Op != NumArgOperands; ++Op)
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
PushValueAndType(FuncletPad.getArgOperand(Op), InstID, Vals, VE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::CatchSwitch: {
|
|
|
|
Code = bitc::FUNC_CODE_INST_CATCHSWITCH;
|
|
|
|
const auto &CatchSwitch = cast<CatchSwitchInst>(I);
|
|
|
|
|
|
|
|
pushValue(CatchSwitch.getParentPad(), InstID, Vals, VE);
|
|
|
|
|
|
|
|
unsigned NumHandlers = CatchSwitch.getNumHandlers();
|
|
|
|
Vals.push_back(NumHandlers);
|
|
|
|
for (const BasicBlock *CatchPadBB : CatchSwitch.handlers())
|
|
|
|
Vals.push_back(VE.getValueID(CatchPadBB));
|
|
|
|
|
|
|
|
if (CatchSwitch.hasUnwindDest())
|
|
|
|
Vals.push_back(VE.getValueID(CatchSwitch.getUnwindDest()));
|
2015-08-01 01:58:14 +08:00
|
|
|
break;
|
|
|
|
}
|
2007-04-26 13:53:54 +08:00
|
|
|
case Instruction::Unreachable:
|
|
|
|
Code = bitc::FUNC_CODE_INST_UNREACHABLE;
|
2007-05-06 09:28:01 +08:00
|
|
|
AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
|
2007-04-26 13:53:54 +08:00
|
|
|
break;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2011-06-20 22:18:48 +08:00
|
|
|
case Instruction::PHI: {
|
|
|
|
const PHINode &PN = cast<PHINode>(I);
|
2007-05-01 10:13:26 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_PHI;
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
// With the newer instruction encoding, forward references could give
|
|
|
|
// negative valued IDs. This is most common for PHIs, so we use
|
|
|
|
// signed VBRs.
|
|
|
|
SmallVector<uint64_t, 128> Vals64;
|
|
|
|
Vals64.push_back(VE.getTypeID(PN.getType()));
|
2011-06-20 22:18:48 +08:00
|
|
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValueSigned(PN.getIncomingValue(i), InstID, Vals64, VE);
|
|
|
|
Vals64.push_back(VE.getValueID(PN.getIncomingBlock(i)));
|
2011-06-20 22:18:48 +08:00
|
|
|
}
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
// Emit a Vals64 vector and exit.
|
|
|
|
Stream.EmitRecord(Code, Vals64, AbbrevToUse);
|
|
|
|
Vals64.clear();
|
|
|
|
return;
|
2011-06-20 22:18:48 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2011-08-13 04:24:12 +08:00
|
|
|
case Instruction::LandingPad: {
|
|
|
|
const LandingPadInst &LP = cast<LandingPadInst>(I);
|
|
|
|
Code = bitc::FUNC_CODE_INST_LANDINGPAD;
|
|
|
|
Vals.push_back(VE.getTypeID(LP.getType()));
|
|
|
|
Vals.push_back(LP.isCleanup());
|
|
|
|
Vals.push_back(LP.getNumClauses());
|
|
|
|
for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) {
|
|
|
|
if (LP.isCatch(I))
|
|
|
|
Vals.push_back(LandingPadInst::Catch);
|
|
|
|
else
|
|
|
|
Vals.push_back(LandingPadInst::Filter);
|
|
|
|
PushValueAndType(LP.getClause(I), InstID, Vals, VE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-07-16 09:34:27 +08:00
|
|
|
case Instruction::Alloca: {
|
2007-05-01 10:13:26 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_ALLOCA;
|
2015-04-29 00:51:01 +08:00
|
|
|
const AllocaInst &AI = cast<AllocaInst>(I);
|
|
|
|
Vals.push_back(VE.getTypeID(AI.getAllocatedType()));
|
2010-05-28 09:38:28 +08:00
|
|
|
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
|
2007-05-01 10:13:26 +08:00
|
|
|
Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
|
2014-07-16 09:34:27 +08:00
|
|
|
unsigned AlignRecord = Log2_32(AI.getAlignment()) + 1;
|
|
|
|
assert(Log2_32(Value::MaximumAlignment) + 1 < 1 << 5 &&
|
|
|
|
"not enough bits for maximum alignment");
|
|
|
|
assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64");
|
|
|
|
AlignRecord |= AI.isUsedWithInAlloca() << 5;
|
2015-04-29 00:51:01 +08:00
|
|
|
AlignRecord |= 1 << 6;
|
2016-04-02 05:41:15 +08:00
|
|
|
AlignRecord |= AI.isSwiftError() << 7;
|
2014-07-16 09:34:27 +08:00
|
|
|
Vals.push_back(AlignRecord);
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
2014-07-16 09:34:27 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-01 10:13:26 +08:00
|
|
|
case Instruction::Load:
|
2011-08-10 07:02:53 +08:00
|
|
|
if (cast<LoadInst>(I).isAtomic()) {
|
|
|
|
Code = bitc::FUNC_CODE_INST_LOADATOMIC;
|
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
|
|
|
|
} else {
|
|
|
|
Code = bitc::FUNC_CODE_INST_LOAD;
|
|
|
|
if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) // ptr
|
|
|
|
AbbrevToUse = FUNCTION_INST_LOAD_ABBREV;
|
|
|
|
}
|
2015-02-25 09:07:20 +08:00
|
|
|
Vals.push_back(VE.getTypeID(I.getType()));
|
2007-05-01 10:13:26 +08:00
|
|
|
Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1);
|
|
|
|
Vals.push_back(cast<LoadInst>(I).isVolatile());
|
2011-08-10 07:02:53 +08:00
|
|
|
if (cast<LoadInst>(I).isAtomic()) {
|
|
|
|
Vals.push_back(GetEncodedOrdering(cast<LoadInst>(I).getOrdering()));
|
|
|
|
Vals.push_back(GetEncodedSynchScope(cast<LoadInst>(I).getSynchScope()));
|
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
|
|
|
case Instruction::Store:
|
2011-08-10 07:02:53 +08:00
|
|
|
if (cast<StoreInst>(I).isAtomic())
|
|
|
|
Code = bitc::FUNC_CODE_INST_STOREATOMIC;
|
|
|
|
else
|
|
|
|
Code = bitc::FUNC_CODE_INST_STORE;
|
2007-12-11 16:59:05 +08:00
|
|
|
PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr
|
2015-04-22 12:14:42 +08:00
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE); // valty + val
|
2007-05-01 10:13:26 +08:00
|
|
|
Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
|
|
|
|
Vals.push_back(cast<StoreInst>(I).isVolatile());
|
2011-08-10 07:02:53 +08:00
|
|
|
if (cast<StoreInst>(I).isAtomic()) {
|
|
|
|
Vals.push_back(GetEncodedOrdering(cast<StoreInst>(I).getOrdering()));
|
|
|
|
Vals.push_back(GetEncodedSynchScope(cast<StoreInst>(I).getSynchScope()));
|
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
break;
|
2011-07-29 05:48:00 +08:00
|
|
|
case Instruction::AtomicCmpXchg:
|
|
|
|
Code = bitc::FUNC_CODE_INST_CMPXCHG;
|
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr
|
2016-01-20 02:01:20 +08:00
|
|
|
PushValueAndType(I.getOperand(1), InstID, Vals, VE); // cmp.
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(2), InstID, Vals, VE); // newval.
|
2011-07-29 05:48:00 +08:00
|
|
|
Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile());
|
|
|
|
Vals.push_back(GetEncodedOrdering(
|
2014-03-11 18:48:52 +08:00
|
|
|
cast<AtomicCmpXchgInst>(I).getSuccessOrdering()));
|
2011-07-29 05:48:00 +08:00
|
|
|
Vals.push_back(GetEncodedSynchScope(
|
|
|
|
cast<AtomicCmpXchgInst>(I).getSynchScope()));
|
2014-03-11 18:48:52 +08:00
|
|
|
Vals.push_back(GetEncodedOrdering(
|
|
|
|
cast<AtomicCmpXchgInst>(I).getFailureOrdering()));
|
IR: add "cmpxchg weak" variant to support permitted failure.
This commit adds a weak variant of the cmpxchg operation, as described
in C++11. A cmpxchg instruction with this modifier is permitted to
fail to store, even if the comparison indicated it should.
As a result, cmpxchg instructions must return a flag indicating
success in addition to their original iN value loaded. Thus, for
uniformity *all* cmpxchg instructions now return "{ iN, i1 }". The
second flag is 1 when the store succeeded.
At the DAG level, a new ATOMIC_CMP_SWAP_WITH_SUCCESS node has been
added as the natural representation for the new cmpxchg instructions.
It is a strong cmpxchg.
By default this gets Expanded to the existing ATOMIC_CMP_SWAP during
Legalization, so existing backends should see no change in behaviour.
If they wish to deal with the enhanced node instead, they can call
setOperationAction on it. Beware: as a node with 2 results, it cannot
be selected from TableGen.
Currently, no use is made of the extra information provided in this
patch. Test updates are almost entirely adapting the input IR to the
new scheme.
Summary for out of tree users:
------------------------------
+ Legacy Bitcode files are upgraded during read.
+ Legacy assembly IR files will be invalid.
+ Front-ends must adapt to different type for "cmpxchg".
+ Backends should be unaffected by default.
llvm-svn: 210903
2014-06-13 22:24:07 +08:00
|
|
|
Vals.push_back(cast<AtomicCmpXchgInst>(I).isWeak());
|
2011-07-29 05:48:00 +08:00
|
|
|
break;
|
|
|
|
case Instruction::AtomicRMW:
|
|
|
|
Code = bitc::FUNC_CODE_INST_ATOMICRMW;
|
|
|
|
PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(1), InstID, Vals, VE); // val.
|
2011-07-29 05:48:00 +08:00
|
|
|
Vals.push_back(GetEncodedRMWOperation(
|
|
|
|
cast<AtomicRMWInst>(I).getOperation()));
|
|
|
|
Vals.push_back(cast<AtomicRMWInst>(I).isVolatile());
|
|
|
|
Vals.push_back(GetEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering()));
|
|
|
|
Vals.push_back(GetEncodedSynchScope(
|
|
|
|
cast<AtomicRMWInst>(I).getSynchScope()));
|
|
|
|
break;
|
2011-07-26 07:16:38 +08:00
|
|
|
case Instruction::Fence:
|
|
|
|
Code = bitc::FUNC_CODE_INST_FENCE;
|
|
|
|
Vals.push_back(GetEncodedOrdering(cast<FenceInst>(I).getOrdering()));
|
|
|
|
Vals.push_back(GetEncodedSynchScope(cast<FenceInst>(I).getSynchScope()));
|
|
|
|
break;
|
2007-05-01 10:13:26 +08:00
|
|
|
case Instruction::Call: {
|
2010-06-26 17:35:09 +08:00
|
|
|
const CallInst &CI = cast<CallInst>(I);
|
2015-04-17 14:40:14 +08:00
|
|
|
FunctionType *FTy = CI.getFunctionType();
|
2007-05-08 13:38:01 +08:00
|
|
|
|
2015-09-25 07:34:52 +08:00
|
|
|
if (CI.hasOperandBundles())
|
|
|
|
WriteOperandBundles(Stream, &CI, InstID, VE);
|
|
|
|
|
2011-06-18 02:17:37 +08:00
|
|
|
Code = bitc::FUNC_CODE_INST_CALL;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2010-06-26 17:35:09 +08:00
|
|
|
Vals.push_back(VE.getAttributeID(CI.getAttributes()));
|
2015-12-15 05:59:03 +08:00
|
|
|
|
|
|
|
unsigned Flags = GetOptimizationFlags(&I);
|
2015-11-07 10:48:49 +08:00
|
|
|
Vals.push_back(CI.getCallingConv() << bitc::CALL_CCONV |
|
|
|
|
unsigned(CI.isTailCall()) << bitc::CALL_TAIL |
|
|
|
|
unsigned(CI.isMustTailCall()) << bitc::CALL_MUSTTAIL |
|
|
|
|
1 << bitc::CALL_EXPLICIT_TYPE |
|
2015-12-15 05:59:03 +08:00
|
|
|
unsigned(CI.isNoTailCall()) << bitc::CALL_NOTAIL |
|
|
|
|
unsigned(Flags != 0) << bitc::CALL_FMF);
|
|
|
|
if (Flags != 0)
|
|
|
|
Vals.push_back(Flags);
|
|
|
|
|
2015-04-17 14:40:14 +08:00
|
|
|
Vals.push_back(VE.getTypeID(FTy));
|
2010-06-26 17:35:09 +08:00
|
|
|
PushValueAndType(CI.getCalledValue(), InstID, Vals, VE); // Callee
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-01 10:13:26 +08:00
|
|
|
// Emit value #'s for the fixed parameters.
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
|
|
|
|
// Check for labels (can happen with asm labels).
|
|
|
|
if (FTy->getParamType(i)->isLabelTy())
|
|
|
|
Vals.push_back(VE.getValueID(CI.getArgOperand(i)));
|
|
|
|
else
|
|
|
|
pushValue(CI.getArgOperand(i), InstID, Vals, VE); // fixed param.
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-01 15:03:37 +08:00
|
|
|
// Emit type/value pairs for varargs params.
|
|
|
|
if (FTy->isVarArg()) {
|
2010-06-26 17:35:09 +08:00
|
|
|
for (unsigned i = FTy->getNumParams(), e = CI.getNumArgOperands();
|
2007-05-06 08:00:00 +08:00
|
|
|
i != e; ++i)
|
2010-06-26 17:35:09 +08:00
|
|
|
PushValueAndType(CI.getArgOperand(i), InstID, Vals, VE); // varargs
|
2007-05-01 10:13:26 +08:00
|
|
|
}
|
|
|
|
break;
|
2007-05-01 15:03:37 +08:00
|
|
|
}
|
2007-05-01 10:13:26 +08:00
|
|
|
case Instruction::VAArg:
|
|
|
|
Code = bitc::FUNC_CODE_INST_VAARG;
|
|
|
|
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); // valistty
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
pushValue(I.getOperand(0), InstID, Vals, VE); // valist.
|
2007-05-01 10:13:26 +08:00
|
|
|
Vals.push_back(VE.getTypeID(I.getType())); // restype.
|
|
|
|
break;
|
2007-04-26 13:53:54 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-26 13:53:54 +08:00
|
|
|
Stream.EmitRecord(Code, Vals, AbbrevToUse);
|
|
|
|
Vals.clear();
|
|
|
|
}
|
|
|
|
|
2015-09-18 04:12:00 +08:00
|
|
|
/// Emit names for globals/functions etc. The VSTOffsetPlaceholder,
|
2016-03-15 08:04:37 +08:00
|
|
|
/// BitcodeStartBit and ModuleSummaryIndex are only passed for the module-level
|
2015-09-18 04:12:00 +08:00
|
|
|
/// VST, where we are including a function bitcode index and need to
|
|
|
|
/// backpatch the VST forward declaration record.
|
|
|
|
static void WriteValueSymbolTable(
|
|
|
|
const ValueSymbolTable &VST, const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream, uint64_t VSTOffsetPlaceholder = 0,
|
|
|
|
uint64_t BitcodeStartBit = 0,
|
2016-04-11 21:58:45 +08:00
|
|
|
DenseMap<const Function *, uint64_t> *FunctionToBitcodeIndex = nullptr) {
|
2015-09-18 04:12:00 +08:00
|
|
|
if (VST.empty()) {
|
|
|
|
// WriteValueSymbolTableForwardDecl should have returned early as
|
|
|
|
// well. Ensure this handling remains in sync by asserting that
|
|
|
|
// the placeholder offset is not set.
|
|
|
|
assert(VSTOffsetPlaceholder == 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VSTOffsetPlaceholder > 0) {
|
|
|
|
// Get the offset of the VST we are writing, and backpatch it into
|
|
|
|
// the VST forward declaration record.
|
|
|
|
uint64_t VSTOffset = Stream.GetCurrentBitNo();
|
|
|
|
// The BitcodeStartBit was the stream offset of the actual bitcode
|
|
|
|
// (e.g. excluding any initial darwin header).
|
|
|
|
VSTOffset -= BitcodeStartBit;
|
|
|
|
assert((VSTOffset & 31) == 0 && "VST block not 32-bit aligned");
|
|
|
|
Stream.BackpatchWord(VSTOffsetPlaceholder, VSTOffset / 32);
|
|
|
|
}
|
|
|
|
|
2007-05-05 09:26:50 +08:00
|
|
|
Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4);
|
2007-05-05 04:34:50 +08:00
|
|
|
|
2015-09-18 04:12:00 +08:00
|
|
|
// For the module-level VST, add abbrev Ids for the VST_CODE_FNENTRY
|
|
|
|
// records, which are not used in the per-function VSTs.
|
|
|
|
unsigned FnEntry8BitAbbrev;
|
|
|
|
unsigned FnEntry7BitAbbrev;
|
|
|
|
unsigned FnEntry6BitAbbrev;
|
|
|
|
if (VSTOffsetPlaceholder > 0) {
|
2016-02-10 23:02:51 +08:00
|
|
|
// 8-bit fixed-width VST_CODE_FNENTRY function strings.
|
2015-09-18 04:12:00 +08:00
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_FNENTRY));
|
2015-11-03 02:02:11 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset
|
2015-09-18 04:12:00 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
|
|
|
|
FnEntry8BitAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
2016-02-10 23:02:51 +08:00
|
|
|
// 7-bit fixed width VST_CODE_FNENTRY function strings.
|
2015-09-18 04:12:00 +08:00
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_FNENTRY));
|
2015-11-03 02:02:11 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset
|
2015-09-18 04:12:00 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
|
|
|
|
FnEntry7BitAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
2016-02-10 23:02:51 +08:00
|
|
|
// 6-bit char6 VST_CODE_FNENTRY function strings.
|
2015-09-18 04:12:00 +08:00
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_FNENTRY));
|
2015-11-03 02:02:11 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset
|
2015-09-18 04:12:00 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
|
|
|
|
FnEntry6BitAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
}
|
|
|
|
|
2007-05-01 10:14:57 +08:00
|
|
|
// FIXME: Set up the abbrev, we know how many values there are!
|
|
|
|
// FIXME: We know if the type names can use 7-bit ascii.
|
|
|
|
SmallVector<unsigned, 64> NameVals;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2015-08-10 15:04:29 +08:00
|
|
|
for (const ValueName &Name : VST) {
|
2007-05-05 04:52:02 +08:00
|
|
|
// Figure out the encoding to use for the name.
|
2015-09-17 22:37:35 +08:00
|
|
|
StringEncoding Bits =
|
|
|
|
getStringEncoding(Name.getKeyData(), Name.getKeyLength());
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 05:31:13 +08:00
|
|
|
unsigned AbbrevToUse = VST_ENTRY_8_ABBREV;
|
2015-09-18 04:12:00 +08:00
|
|
|
NameVals.push_back(VE.getValueID(Name.getValue()));
|
|
|
|
|
|
|
|
Function *F = dyn_cast<Function>(Name.getValue());
|
|
|
|
if (!F) {
|
|
|
|
// If value is an alias, need to get the aliased base object to
|
|
|
|
// see if it is a function.
|
|
|
|
auto *GA = dyn_cast<GlobalAlias>(Name.getValue());
|
|
|
|
if (GA && GA->getBaseObject())
|
|
|
|
F = dyn_cast<Function>(GA->getBaseObject());
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2016-02-10 23:02:51 +08:00
|
|
|
// VST_CODE_ENTRY: [valueid, namechar x N]
|
|
|
|
// VST_CODE_FNENTRY: [valueid, funcoffset, namechar x N]
|
|
|
|
// VST_CODE_BBENTRY: [bbid, namechar x N]
|
2007-05-04 06:18:21 +08:00
|
|
|
unsigned Code;
|
2015-08-10 15:04:29 +08:00
|
|
|
if (isa<BasicBlock>(Name.getValue())) {
|
2011-04-11 07:18:04 +08:00
|
|
|
Code = bitc::VST_CODE_BBENTRY;
|
2015-09-17 22:37:35 +08:00
|
|
|
if (Bits == SE_Char6)
|
2011-04-11 07:18:04 +08:00
|
|
|
AbbrevToUse = VST_BBENTRY_6_ABBREV;
|
2015-09-18 04:12:00 +08:00
|
|
|
} else if (F && !F->isDeclaration()) {
|
|
|
|
// Must be the module-level VST, where we pass in the Index and
|
|
|
|
// have a VSTOffsetPlaceholder. The function-level VST should not
|
|
|
|
// contain any Function symbols.
|
2016-04-11 21:58:45 +08:00
|
|
|
assert(FunctionToBitcodeIndex);
|
2015-09-18 04:12:00 +08:00
|
|
|
assert(VSTOffsetPlaceholder > 0);
|
|
|
|
|
|
|
|
// Save the word offset of the function (from the start of the
|
|
|
|
// actual bitcode written to the stream).
|
2016-04-11 21:58:45 +08:00
|
|
|
uint64_t BitcodeIndex = (*FunctionToBitcodeIndex)[F] - BitcodeStartBit;
|
2015-09-18 04:12:00 +08:00
|
|
|
assert((BitcodeIndex & 31) == 0 && "function block not 32-bit aligned");
|
|
|
|
NameVals.push_back(BitcodeIndex / 32);
|
|
|
|
|
|
|
|
Code = bitc::VST_CODE_FNENTRY;
|
|
|
|
AbbrevToUse = FnEntry8BitAbbrev;
|
|
|
|
if (Bits == SE_Char6)
|
|
|
|
AbbrevToUse = FnEntry6BitAbbrev;
|
|
|
|
else if (Bits == SE_Fixed7)
|
|
|
|
AbbrevToUse = FnEntry7BitAbbrev;
|
2007-05-04 06:18:21 +08:00
|
|
|
} else {
|
|
|
|
Code = bitc::VST_CODE_ENTRY;
|
2015-09-17 22:37:35 +08:00
|
|
|
if (Bits == SE_Char6)
|
2007-05-05 09:26:50 +08:00
|
|
|
AbbrevToUse = VST_ENTRY_6_ABBREV;
|
2015-09-17 22:37:35 +08:00
|
|
|
else if (Bits == SE_Fixed7)
|
2007-05-05 09:26:50 +08:00
|
|
|
AbbrevToUse = VST_ENTRY_7_ABBREV;
|
2007-05-04 06:18:21 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2015-11-03 02:02:11 +08:00
|
|
|
for (const auto P : Name.getKey())
|
|
|
|
NameVals.push_back((unsigned char)P);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-01 10:14:57 +08:00
|
|
|
// Emit the finished record.
|
2007-05-04 06:18:21 +08:00
|
|
|
Stream.EmitRecord(Code, NameVals, AbbrevToUse);
|
2007-05-01 10:14:57 +08:00
|
|
|
NameVals.clear();
|
|
|
|
}
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2015-10-04 22:33:43 +08:00
|
|
|
/// Emit function names and summary offsets for the combined index
|
|
|
|
/// used by ThinLTO.
|
2016-04-02 13:07:53 +08:00
|
|
|
static void WriteCombinedValueSymbolTable(
|
|
|
|
const ModuleSummaryIndex &Index, BitstreamWriter &Stream,
|
|
|
|
std::map<GlobalValue::GUID, unsigned> &GUIDToValueIdMap,
|
|
|
|
uint64_t VSTOffsetPlaceholder) {
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
assert(VSTOffsetPlaceholder > 0 && "Expected non-zero VSTOffsetPlaceholder");
|
|
|
|
// Get the offset of the VST we are writing, and backpatch it into
|
|
|
|
// the VST forward declaration record.
|
|
|
|
uint64_t VSTOffset = Stream.GetCurrentBitNo();
|
|
|
|
assert((VSTOffset & 31) == 0 && "VST block not 32-bit aligned");
|
|
|
|
Stream.BackpatchWord(VSTOffsetPlaceholder, VSTOffset / 32);
|
|
|
|
|
2015-10-04 22:33:43 +08:00
|
|
|
Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4);
|
|
|
|
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_GVDEFENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // sumoffset
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // guid
|
|
|
|
unsigned DefEntryAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_ENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // refguid
|
|
|
|
unsigned EntryAbbrev = Stream.EmitAbbrev(Abbv);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2016-02-11 05:55:02 +08:00
|
|
|
SmallVector<uint64_t, 64> NameVals;
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2015-10-20 03:06:06 +08:00
|
|
|
for (const auto &FII : Index) {
|
2016-04-02 13:07:53 +08:00
|
|
|
GlobalValue::GUID FuncGUID = FII.first;
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
const auto &VMI = GUIDToValueIdMap.find(FuncGUID);
|
|
|
|
assert(VMI != GUIDToValueIdMap.end());
|
|
|
|
|
2016-02-11 05:55:02 +08:00
|
|
|
for (const auto &FI : FII.second) {
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// VST_CODE_COMBINED_GVDEFENTRY: [valueid, sumoffset, guid]
|
|
|
|
NameVals.push_back(VMI->second);
|
2015-10-04 22:33:43 +08:00
|
|
|
NameVals.push_back(FI->bitcodeIndex());
|
2016-02-11 05:55:02 +08:00
|
|
|
NameVals.push_back(FuncGUID);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
// Emit the finished record.
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Stream.EmitRecord(bitc::VST_CODE_COMBINED_GVDEFENTRY, NameVals,
|
|
|
|
DefEntryAbbrev);
|
2015-10-04 22:33:43 +08:00
|
|
|
NameVals.clear();
|
|
|
|
}
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
GUIDToValueIdMap.erase(VMI);
|
|
|
|
}
|
|
|
|
for (const auto &GVI : GUIDToValueIdMap) {
|
|
|
|
// VST_CODE_COMBINED_ENTRY: [valueid, refguid]
|
|
|
|
NameVals.push_back(GVI.second);
|
|
|
|
NameVals.push_back(GVI.first);
|
|
|
|
|
|
|
|
// Emit the finished record.
|
|
|
|
Stream.EmitRecord(bitc::VST_CODE_COMBINED_ENTRY, NameVals, EntryAbbrev);
|
|
|
|
NameVals.clear();
|
2015-10-04 22:33:43 +08:00
|
|
|
}
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2014-07-29 05:19:41 +08:00
|
|
|
static void WriteUseList(ValueEnumerator &VE, UseListOrder &&Order,
|
|
|
|
BitstreamWriter &Stream) {
|
|
|
|
assert(Order.Shuffle.size() >= 2 && "Shuffle too small");
|
|
|
|
unsigned Code;
|
|
|
|
if (isa<BasicBlock>(Order.V))
|
|
|
|
Code = bitc::USELIST_CODE_BB;
|
|
|
|
else
|
|
|
|
Code = bitc::USELIST_CODE_DEFAULT;
|
|
|
|
|
2015-02-17 23:29:18 +08:00
|
|
|
SmallVector<uint64_t, 64> Record(Order.Shuffle.begin(), Order.Shuffle.end());
|
2014-07-29 05:19:41 +08:00
|
|
|
Record.push_back(VE.getValueID(Order.V));
|
|
|
|
Stream.EmitRecord(Code, Record);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WriteUseListBlock(const Function *F, ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
2015-04-15 07:45:11 +08:00
|
|
|
assert(VE.shouldPreserveUseListOrder() &&
|
|
|
|
"Expected to be preserving use-list order");
|
|
|
|
|
2014-07-29 05:19:41 +08:00
|
|
|
auto hasMore = [&]() {
|
|
|
|
return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F;
|
|
|
|
};
|
|
|
|
if (!hasMore())
|
|
|
|
// Nothing to do.
|
|
|
|
return;
|
|
|
|
|
|
|
|
Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3);
|
|
|
|
while (hasMore()) {
|
|
|
|
WriteUseList(VE, std::move(VE.UseListOrders.back()), Stream);
|
|
|
|
VE.UseListOrders.pop_back();
|
|
|
|
}
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2015-10-04 22:33:43 +08:00
|
|
|
/// Emit a function body to the module stream.
|
2016-04-03 01:29:47 +08:00
|
|
|
static void
|
|
|
|
WriteFunction(const Function &F, const Module *M, ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream,
|
2016-04-11 21:58:45 +08:00
|
|
|
DenseMap<const Function *, uint64_t> &FunctionToBitcodeIndex) {
|
2015-09-18 04:12:00 +08:00
|
|
|
// Save the bitcode index of the start of this function block for recording
|
|
|
|
// in the VST.
|
2016-04-11 21:58:45 +08:00
|
|
|
FunctionToBitcodeIndex[&F] = Stream.GetCurrentBitNo();
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
|
2007-05-06 10:38:57 +08:00
|
|
|
Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);
|
2011-06-04 01:02:19 +08:00
|
|
|
VE.incorporateFunction(F);
|
2007-04-26 13:53:54 +08:00
|
|
|
|
|
|
|
SmallVector<unsigned, 64> Vals;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-26 13:53:54 +08:00
|
|
|
// Emit the number of basic blocks, so the reader can create them ahead of
|
|
|
|
// time.
|
|
|
|
Vals.push_back(VE.getBasicBlocks().size());
|
|
|
|
Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals);
|
|
|
|
Vals.clear();
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-26 13:53:54 +08:00
|
|
|
// If there are function-local constants, emit them now.
|
|
|
|
unsigned CstStart, CstEnd;
|
|
|
|
VE.getFunctionConstantRange(CstStart, CstEnd);
|
2009-08-04 13:01:35 +08:00
|
|
|
WriteConstants(CstStart, CstEnd, VE, Stream, false);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2010-01-14 09:50:08 +08:00
|
|
|
// If there is function-local metadata, emit it now.
|
2016-03-28 07:56:04 +08:00
|
|
|
writeFunctionMetadata(F, VE, Stream);
|
2010-01-14 09:50:08 +08:00
|
|
|
|
2009-09-20 10:20:51 +08:00
|
|
|
// Keep a running idea of what the instruction ID is.
|
2007-05-06 08:00:00 +08:00
|
|
|
unsigned InstID = CstEnd;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2015-04-25 06:04:41 +08:00
|
|
|
bool NeedsMetadataAttachment = F.hasMetadata();
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2015-04-30 00:38:44 +08:00
|
|
|
DILocation *LastDL = nullptr;
|
2007-04-26 13:53:54 +08:00
|
|
|
// Finally, emit all the instructions, in order.
|
2008-04-26 00:53:59 +08:00
|
|
|
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
2007-05-06 08:00:00 +08:00
|
|
|
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
|
|
|
|
I != E; ++I) {
|
|
|
|
WriteInstruction(*I, InstID, VE, Stream, Vals);
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2009-12-29 07:41:32 +08:00
|
|
|
if (!I->getType()->isVoidTy())
|
2007-05-06 08:00:00 +08:00
|
|
|
++InstID;
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2010-04-03 10:17:50 +08:00
|
|
|
// If the instruction has metadata, write a metadata attachment later.
|
|
|
|
NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
|
2012-11-16 06:34:00 +08:00
|
|
|
|
2010-04-03 10:17:50 +08:00
|
|
|
// If the instruction has a debug location, emit it.
|
2015-04-30 00:38:44 +08:00
|
|
|
DILocation *DL = I->getDebugLoc();
|
2015-03-31 03:40:05 +08:00
|
|
|
if (!DL)
|
2015-03-31 02:29:18 +08:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (DL == LastDL) {
|
2010-04-03 10:17:50 +08:00
|
|
|
// Just repeat the same debug loc as last time.
|
|
|
|
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
|
2015-03-31 02:29:18 +08:00
|
|
|
continue;
|
2010-04-03 10:17:50 +08:00
|
|
|
}
|
2015-03-31 02:29:18 +08:00
|
|
|
|
2015-03-31 03:40:05 +08:00
|
|
|
Vals.push_back(DL->getLine());
|
|
|
|
Vals.push_back(DL->getColumn());
|
|
|
|
Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
|
|
|
|
Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
|
2015-03-31 02:29:18 +08:00
|
|
|
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
|
|
|
|
Vals.clear();
|
2015-05-07 06:51:12 +08:00
|
|
|
|
|
|
|
LastDL = DL;
|
2007-05-06 08:00:00 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-01 10:14:57 +08:00
|
|
|
// Emit names for all the instructions etc.
|
|
|
|
WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
|
2009-09-19 03:26:43 +08:00
|
|
|
|
2010-04-03 10:17:50 +08:00
|
|
|
if (NeedsMetadataAttachment)
|
|
|
|
WriteMetadataAttachment(F, VE, Stream);
|
2015-04-15 07:45:11 +08:00
|
|
|
if (VE.shouldPreserveUseListOrder())
|
2014-07-29 05:19:41 +08:00
|
|
|
WriteUseListBlock(&F, VE, Stream);
|
2011-06-04 01:02:19 +08:00
|
|
|
VE.purgeFunction();
|
2007-04-26 13:53:54 +08:00
|
|
|
Stream.ExitBlock();
|
2007-04-26 11:27:58 +08:00
|
|
|
}
|
|
|
|
|
2007-05-05 15:36:14 +08:00
|
|
|
// Emit blockinfo, which defines the standard abbreviations etc.
|
|
|
|
static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
|
|
|
// We only want to emit block info records for blocks that have multiple
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
// instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.
|
2012-10-12 05:45:16 +08:00
|
|
|
// Other blocks can define their abbrevs inline.
|
2007-05-05 15:36:14 +08:00
|
|
|
Stream.EnterBlockInfoBlock(2);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2016-02-10 23:02:51 +08:00
|
|
|
{ // 8-bit fixed-width VST_CODE_ENTRY/VST_CODE_BBENTRY strings.
|
2007-05-05 15:36:14 +08:00
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
|
2009-09-20 10:20:51 +08:00
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
|
2007-05-05 15:36:14 +08:00
|
|
|
Abbv) != VST_ENTRY_8_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2016-02-10 23:02:51 +08:00
|
|
|
{ // 7-bit fixed width VST_CODE_ENTRY strings.
|
2007-05-05 15:36:14 +08:00
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
|
|
|
|
Abbv) != VST_ENTRY_7_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
2016-02-10 23:02:51 +08:00
|
|
|
{ // 6-bit char6 VST_CODE_ENTRY strings.
|
2007-05-05 15:36:14 +08:00
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
|
|
|
|
Abbv) != VST_ENTRY_6_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
2016-02-10 23:02:51 +08:00
|
|
|
{ // 6-bit char6 VST_CODE_BBENTRY strings.
|
2007-05-05 15:36:14 +08:00
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
|
|
|
|
Abbv) != VST_BBENTRY_6_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
2011-04-11 07:18:04 +08:00
|
|
|
|
|
|
|
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:36:14 +08:00
|
|
|
{ // SETTYPE abbrev for CONSTANTS_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
|
2015-02-25 08:51:52 +08:00
|
|
|
VE.computeBitsRequiredForTypeIndicies()));
|
2007-05-05 15:36:14 +08:00
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
|
|
|
|
Abbv) != CONSTANTS_SETTYPE_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:36:14 +08:00
|
|
|
{ // INTEGER abbrev for CONSTANTS_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
|
|
|
|
Abbv) != CONSTANTS_INTEGER_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:36:14 +08:00
|
|
|
{ // CE_CAST abbrev for CONSTANTS_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // cast opc
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // typeid
|
2015-02-25 08:51:52 +08:00
|
|
|
VE.computeBitsRequiredForTypeIndicies()));
|
2007-05-05 15:36:14 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id
|
|
|
|
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
|
|
|
|
Abbv) != CONSTANTS_CE_CAST_Abbrev)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
|
|
|
{ // NULL abbrev for CONSTANTS_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
|
|
|
|
Abbv) != CONSTANTS_NULL_Abbrev)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:36:14 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:44:49 +08:00
|
|
|
// FIXME: This should only use space for first class types!
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:44:49 +08:00
|
|
|
{ // INST_LOAD abbrev for FUNCTION_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr
|
2015-02-25 09:07:20 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
|
|
|
|
VE.computeBitsRequiredForTypeIndicies()));
|
2007-05-05 15:44:49 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
|
|
|
Abbv) != FUNCTION_INST_LOAD_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-05 15:44:49 +08:00
|
|
|
}
|
2007-05-06 10:38:57 +08:00
|
|
|
{ // INST_BINOP abbrev for FUNCTION_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
|
|
|
Abbv) != FUNCTION_INST_BINOP_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-06 10:38:57 +08:00
|
|
|
}
|
2009-07-21 05:19:07 +08:00
|
|
|
{ // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
|
|
|
Abbv) != FUNCTION_INST_BINOP_FLAGS_ABBREV)
|
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
|
|
|
}
|
2007-05-06 10:38:57 +08:00
|
|
|
{ // INST_CAST abbrev for FUNCTION_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpVal
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
|
2015-02-25 08:51:52 +08:00
|
|
|
VE.computeBitsRequiredForTypeIndicies()));
|
2007-05-06 10:38:57 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
|
|
|
Abbv) != FUNCTION_INST_CAST_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-06 10:38:57 +08:00
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-06 09:28:01 +08:00
|
|
|
{ // INST_RET abbrev for FUNCTION_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
|
|
|
Abbv) != FUNCTION_INST_RET_VOID_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-06 09:28:01 +08:00
|
|
|
}
|
|
|
|
{ // INST_RET abbrev for FUNCTION_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
|
|
|
Abbv) != FUNCTION_INST_RET_VAL_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-06 09:28:01 +08:00
|
|
|
}
|
|
|
|
{ // INST_UNREACHABLE abbrev for FUNCTION_BLOCK.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
|
|
|
|
Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
2007-05-06 09:28:01 +08:00
|
|
|
}
|
2015-02-25 09:08:52 +08:00
|
|
|
{
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_GEP));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
|
|
|
|
Log2_32_Ceil(VE.getTypes().size() + 1)));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
|
|
|
|
FUNCTION_INST_GEP_ABBREV)
|
|
|
|
llvm_unreachable("Unexpected abbrev ordering!");
|
|
|
|
}
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-05-05 15:36:14 +08:00
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2015-10-04 22:33:43 +08:00
|
|
|
/// Write the module path strings, currently only used when generating
|
|
|
|
/// a combined index file.
|
2016-03-15 08:04:37 +08:00
|
|
|
static void WriteModStrings(const ModuleSummaryIndex &I,
|
2015-10-04 22:33:43 +08:00
|
|
|
BitstreamWriter &Stream) {
|
|
|
|
Stream.EnterSubblock(bitc::MODULE_STRTAB_BLOCK_ID, 3);
|
|
|
|
|
|
|
|
// TODO: See which abbrev sizes we actually need to emit
|
|
|
|
|
|
|
|
// 8-bit fixed-width MST_ENTRY strings.
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::MST_CODE_ENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
|
|
|
|
unsigned Abbrev8Bit = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
// 7-bit fixed width MST_ENTRY strings.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::MST_CODE_ENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
|
|
|
|
unsigned Abbrev7Bit = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
// 6-bit char6 MST_ENTRY strings.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::MST_CODE_ENTRY));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
|
|
|
|
unsigned Abbrev6Bit = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
2016-04-01 13:33:11 +08:00
|
|
|
// Module Hash, 160 bits SHA1. Optionally, emitted after each MST_CODE_ENTRY.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::MST_CODE_HASH));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
|
|
|
|
unsigned AbbrevHash = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
SmallVector<unsigned, 64> Vals;
|
|
|
|
for (const auto &MPSE : I.modulePaths()) {
|
2015-10-04 22:33:43 +08:00
|
|
|
StringEncoding Bits =
|
|
|
|
getStringEncoding(MPSE.getKey().data(), MPSE.getKey().size());
|
|
|
|
unsigned AbbrevToUse = Abbrev8Bit;
|
|
|
|
if (Bits == SE_Char6)
|
|
|
|
AbbrevToUse = Abbrev6Bit;
|
|
|
|
else if (Bits == SE_Fixed7)
|
|
|
|
AbbrevToUse = Abbrev7Bit;
|
|
|
|
|
2016-04-01 13:33:11 +08:00
|
|
|
Vals.push_back(MPSE.getValue().first);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2015-11-03 02:02:11 +08:00
|
|
|
for (const auto P : MPSE.getKey())
|
2016-04-01 13:33:11 +08:00
|
|
|
Vals.push_back((unsigned char)P);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
// Emit the finished record.
|
2016-04-01 13:33:11 +08:00
|
|
|
Stream.EmitRecord(bitc::MST_CODE_ENTRY, Vals, AbbrevToUse);
|
|
|
|
|
|
|
|
Vals.clear();
|
|
|
|
// Emit an optional hash for the module now
|
|
|
|
auto &Hash = MPSE.getValue().second;
|
|
|
|
bool AllZero = true; // Detect if the hash is empty, and do not generate it
|
|
|
|
for (auto Val : Hash) {
|
|
|
|
if (Val)
|
|
|
|
AllZero = false;
|
|
|
|
Vals.push_back(Val);
|
|
|
|
}
|
|
|
|
if (!AllZero) {
|
|
|
|
// Emit the hash record.
|
|
|
|
Stream.EmitRecord(bitc::MST_CODE_HASH, Vals, AbbrevHash);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vals.clear();
|
2015-10-04 22:33:43 +08:00
|
|
|
}
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper to emit a single function summary record.
|
|
|
|
static void WritePerModuleFunctionSummaryRecord(
|
2016-04-11 21:58:45 +08:00
|
|
|
SmallVector<uint64_t, 64> &NameVals, GlobalValueInfo *Info,
|
|
|
|
unsigned ValueID, const ValueEnumerator &VE, unsigned FSCallsAbbrev,
|
|
|
|
unsigned FSCallsProfileAbbrev, BitstreamWriter &Stream, const Function &F) {
|
2015-10-04 22:33:43 +08:00
|
|
|
NameVals.push_back(ValueID);
|
2016-04-11 21:58:45 +08:00
|
|
|
|
|
|
|
FunctionSummary *FS = cast<FunctionSummary>(Info->summary());
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
NameVals.push_back(getEncodedLinkage(FS->linkage()));
|
2015-10-04 22:33:43 +08:00
|
|
|
NameVals.push_back(FS->instCount());
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
NameVals.push_back(FS->refs().size());
|
|
|
|
|
|
|
|
for (auto &RI : FS->refs())
|
2016-04-11 21:58:45 +08:00
|
|
|
NameVals.push_back(VE.getValueID(RI.getValue()));
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
|
|
|
|
bool HasProfileData = F.getEntryCount().hasValue();
|
2016-03-26 02:59:13 +08:00
|
|
|
for (auto &ECI : FS->calls()) {
|
2016-04-11 21:58:45 +08:00
|
|
|
NameVals.push_back(VE.getValueID(ECI.first.getValue()));
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
assert(ECI.second.CallsiteCount > 0 && "Expected at least one callsite");
|
|
|
|
NameVals.push_back(ECI.second.CallsiteCount);
|
|
|
|
if (HasProfileData)
|
|
|
|
NameVals.push_back(ECI.second.ProfileCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
|
|
|
|
unsigned Code =
|
|
|
|
(HasProfileData ? bitc::FS_PERMODULE_PROFILE : bitc::FS_PERMODULE);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
// Emit the finished record.
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Stream.EmitRecord(Code, NameVals, FSAbbrev);
|
2015-10-04 22:33:43 +08:00
|
|
|
NameVals.clear();
|
|
|
|
}
|
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Collect the global value references in the given variable's initializer,
|
|
|
|
// and emit them in a summary record.
|
|
|
|
static void WriteModuleLevelReferences(const GlobalVariable &V,
|
2016-04-11 21:58:45 +08:00
|
|
|
const ModuleSummaryIndex &Index,
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
const ValueEnumerator &VE,
|
|
|
|
SmallVector<uint64_t, 64> &NameVals,
|
|
|
|
unsigned FSModRefsAbbrev,
|
|
|
|
BitstreamWriter &Stream) {
|
2016-03-16 03:35:45 +08:00
|
|
|
// Only interested in recording variable defs in the summary.
|
|
|
|
if (V.isDeclaration())
|
|
|
|
return;
|
|
|
|
NameVals.push_back(VE.getValueID(&V));
|
|
|
|
NameVals.push_back(getEncodedLinkage(V.getLinkage()));
|
2016-04-11 21:58:45 +08:00
|
|
|
auto *Info = Index.getGlobalValueInfo(V);
|
|
|
|
GlobalVarSummary *VS = cast<GlobalVarSummary>(Info->summary());
|
|
|
|
for (auto Ref : VS->refs())
|
|
|
|
NameVals.push_back(VE.getValueID(Ref.getValue()));
|
2016-03-16 03:35:45 +08:00
|
|
|
Stream.EmitRecord(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS, NameVals,
|
|
|
|
FSModRefsAbbrev);
|
|
|
|
NameVals.clear();
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Emit the per-module summary section alongside the rest of
|
2015-10-04 22:33:43 +08:00
|
|
|
/// the module's bitcode.
|
2016-04-11 21:58:45 +08:00
|
|
|
static void WritePerModuleGlobalValueSummary(const Module *M,
|
|
|
|
const ModuleSummaryIndex &Index,
|
|
|
|
const ValueEnumerator &VE,
|
|
|
|
BitstreamWriter &Stream) {
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
if (M->empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 3);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Abbrev for FS_PERMODULE.
|
2015-10-04 22:33:43 +08:00
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE));
|
2015-11-03 02:02:11 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
2016-02-07 00:07:35 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
2015-11-03 02:02:11 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
|
|
|
// numrefs x valueid, n x (valueid, callsitecount)
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
unsigned FSCallsAbbrev = Stream.EmitAbbrev(Abbv);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Abbrev for FS_PERMODULE_PROFILE.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_PROFILE));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
|
|
|
// numrefs x valueid, n x (valueid, callsitecount, profilecount)
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
// Abbrev for FS_PERMODULE_GLOBALVAR_INIT_REFS.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); // valueids
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
unsigned FSModRefsAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
SmallVector<uint64_t, 64> NameVals;
|
2016-04-11 21:58:45 +08:00
|
|
|
// Iterate over the list of functions instead of the Index to
|
2016-02-02 04:16:35 +08:00
|
|
|
// ensure the ordering is stable.
|
|
|
|
for (const Function &F : *M) {
|
|
|
|
if (F.isDeclaration())
|
|
|
|
continue;
|
2016-04-14 01:20:07 +08:00
|
|
|
// Skip anonymous functions. We will emit a function summary for
|
|
|
|
// any aliases below.
|
2016-02-02 04:16:35 +08:00
|
|
|
if (!F.hasName())
|
2016-04-14 01:20:07 +08:00
|
|
|
continue;
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2016-04-11 21:58:45 +08:00
|
|
|
auto *Info = Index.getGlobalValueInfo(F);
|
2015-10-04 22:33:43 +08:00
|
|
|
WritePerModuleFunctionSummaryRecord(
|
2016-04-11 21:58:45 +08:00
|
|
|
NameVals, Info,
|
|
|
|
VE.getValueID(M->getValueSymbolTable().lookup(F.getName())), VE,
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
FSCallsAbbrev, FSCallsProfileAbbrev, Stream, F);
|
2015-10-04 22:33:43 +08:00
|
|
|
}
|
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Capture references from GlobalVariable initializers, which are outside
|
|
|
|
// of a function scope.
|
|
|
|
for (const GlobalVariable &G : M->globals())
|
2016-04-11 21:58:45 +08:00
|
|
|
WriteModuleLevelReferences(G, Index, VE, NameVals, FSModRefsAbbrev, Stream);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
/// Emit the combined summary section into the combined index file.
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
static void WriteCombinedGlobalValueSummary(
|
2016-04-08 05:49:31 +08:00
|
|
|
const ModuleSummaryIndex &Index, BitstreamWriter &Stream,
|
2016-04-02 13:07:53 +08:00
|
|
|
std::map<GlobalValue::GUID, unsigned> &GUIDToValueIdMap,
|
|
|
|
unsigned GlobalValueId) {
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 3);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Abbrev for FS_COMBINED.
|
2015-10-04 22:33:43 +08:00
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
|
2016-02-07 00:07:35 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
|
|
|
// numrefs x valueid, n x (valueid, callsitecount)
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
unsigned FSCallsAbbrev = Stream.EmitAbbrev(Abbv);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Abbrev for FS_COMBINED_PROFILE.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_PROFILE));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
|
|
|
// numrefs x valueid, n x (valueid, callsitecount, profilecount)
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
// Abbrev for FS_COMBINED_GLOBALVAR_INIT_REFS.
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); // valueids
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
|
|
|
unsigned FSModRefsAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
|
|
|
|
SmallVector<uint64_t, 64> NameVals;
|
2016-04-08 05:49:31 +08:00
|
|
|
for (const auto &FII : Index) {
|
2016-02-11 05:55:02 +08:00
|
|
|
for (auto &FI : FII.second) {
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
GlobalValueSummary *S = FI->summary();
|
|
|
|
assert(S);
|
|
|
|
|
|
|
|
if (auto *VS = dyn_cast<GlobalVarSummary>(S)) {
|
2016-04-08 05:49:31 +08:00
|
|
|
NameVals.push_back(Index.getModuleId(VS->modulePath()));
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
NameVals.push_back(getEncodedLinkage(VS->linkage()));
|
|
|
|
for (auto &RI : VS->refs()) {
|
2016-04-11 21:58:45 +08:00
|
|
|
const auto &VMI = GUIDToValueIdMap.find(RI.getGUID());
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
unsigned RefId;
|
|
|
|
// If this GUID doesn't have an entry, assign one.
|
|
|
|
if (VMI == GUIDToValueIdMap.end()) {
|
2016-04-11 21:58:45 +08:00
|
|
|
GUIDToValueIdMap[RI.getGUID()] = ++GlobalValueId;
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
RefId = GlobalValueId;
|
|
|
|
} else {
|
|
|
|
RefId = VMI->second;
|
|
|
|
}
|
|
|
|
NameVals.push_back(RefId);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Record the starting offset of this summary entry for use
|
|
|
|
// in the VST entry. Add the current code size since the
|
|
|
|
// reader will invoke readRecord after the abbrev id read.
|
|
|
|
FI->setBitcodeIndex(Stream.GetCurrentBitNo() +
|
|
|
|
Stream.GetAbbrevIDWidth());
|
|
|
|
|
|
|
|
// Emit the finished record.
|
|
|
|
Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
|
|
|
|
FSModRefsAbbrev);
|
|
|
|
NameVals.clear();
|
|
|
|
continue;
|
|
|
|
}
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2016-03-15 10:41:29 +08:00
|
|
|
auto *FS = cast<FunctionSummary>(S);
|
2016-04-08 05:49:31 +08:00
|
|
|
NameVals.push_back(Index.getModuleId(FS->modulePath()));
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
NameVals.push_back(getEncodedLinkage(FS->linkage()));
|
2015-10-04 22:33:43 +08:00
|
|
|
NameVals.push_back(FS->instCount());
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
NameVals.push_back(FS->refs().size());
|
|
|
|
|
|
|
|
for (auto &RI : FS->refs()) {
|
2016-04-11 21:58:45 +08:00
|
|
|
const auto &VMI = GUIDToValueIdMap.find(RI.getGUID());
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
unsigned RefId;
|
|
|
|
// If this GUID doesn't have an entry, assign one.
|
|
|
|
if (VMI == GUIDToValueIdMap.end()) {
|
2016-04-11 21:58:45 +08:00
|
|
|
GUIDToValueIdMap[RI.getGUID()] = ++GlobalValueId;
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
RefId = GlobalValueId;
|
|
|
|
} else {
|
|
|
|
RefId = VMI->second;
|
|
|
|
}
|
|
|
|
NameVals.push_back(RefId);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasProfileData = false;
|
2016-03-26 02:59:13 +08:00
|
|
|
for (auto &EI : FS->calls()) {
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
HasProfileData |= EI.second.ProfileCount != 0;
|
|
|
|
if (HasProfileData)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-03-26 02:59:13 +08:00
|
|
|
for (auto &EI : FS->calls()) {
|
2016-04-11 21:58:45 +08:00
|
|
|
const auto &VMI = GUIDToValueIdMap.find(EI.first.getGUID());
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// If this GUID doesn't have an entry, it doesn't have a function
|
|
|
|
// summary and we don't need to record any calls to it.
|
|
|
|
if (VMI == GUIDToValueIdMap.end())
|
|
|
|
continue;
|
|
|
|
NameVals.push_back(VMI->second);
|
|
|
|
assert(EI.second.CallsiteCount > 0 && "Expected at least one callsite");
|
|
|
|
NameVals.push_back(EI.second.CallsiteCount);
|
|
|
|
if (HasProfileData)
|
|
|
|
NameVals.push_back(EI.second.ProfileCount);
|
|
|
|
}
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
// Record the starting offset of this summary entry for use
|
|
|
|
// in the VST entry. Add the current code size since the
|
|
|
|
// reader will invoke readRecord after the abbrev id read.
|
|
|
|
FI->setBitcodeIndex(Stream.GetCurrentBitNo() + Stream.GetAbbrevIDWidth());
|
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
unsigned FSAbbrev =
|
|
|
|
(HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
|
|
|
|
unsigned Code =
|
|
|
|
(HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
|
|
|
|
|
2015-10-04 22:33:43 +08:00
|
|
|
// Emit the finished record.
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
Stream.EmitRecord(Code, NameVals, FSAbbrev);
|
2015-10-04 22:33:43 +08:00
|
|
|
NameVals.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2015-10-27 02:37:00 +08:00
|
|
|
// Create the "IDENTIFICATION_BLOCK_ID" containing a single string with the
|
|
|
|
// current llvm version, and a record for the epoch number.
|
|
|
|
static void WriteIdentificationBlock(const Module *M, BitstreamWriter &Stream) {
|
|
|
|
Stream.EnterSubblock(bitc::IDENTIFICATION_BLOCK_ID, 5);
|
|
|
|
|
|
|
|
// Write the "user readable" string identifying the bitcode producer
|
|
|
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::IDENTIFICATION_CODE_STRING));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
|
|
|
|
auto StringAbbrev = Stream.EmitAbbrev(Abbv);
|
|
|
|
WriteStringRecord(bitc::IDENTIFICATION_CODE_STRING,
|
|
|
|
"LLVM" LLVM_VERSION_STRING, StringAbbrev, Stream);
|
|
|
|
|
|
|
|
// Write the epoch version
|
|
|
|
Abbv = new BitCodeAbbrev();
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(bitc::IDENTIFICATION_CODE_EPOCH));
|
|
|
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
2015-11-05 08:25:03 +08:00
|
|
|
auto EpochAbbrev = Stream.EmitAbbrev(Abbv);
|
2015-10-27 02:37:00 +08:00
|
|
|
SmallVector<unsigned, 1> Vals = {bitc::BITCODE_CURRENT_EPOCH};
|
2015-11-05 08:25:03 +08:00
|
|
|
Stream.EmitRecord(bitc::IDENTIFICATION_CODE_EPOCH, Vals, EpochAbbrev);
|
2015-10-27 02:37:00 +08:00
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2016-04-01 13:33:11 +08:00
|
|
|
static void writeModuleHash(BitstreamWriter &Stream,
|
|
|
|
SmallVectorImpl<char> &Buffer,
|
|
|
|
size_t BlockStartPos) {
|
|
|
|
// Emit the module's hash.
|
|
|
|
// MODULE_CODE_HASH: [5*i32]
|
|
|
|
SHA1 Hasher;
|
|
|
|
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&Buffer[BlockStartPos],
|
|
|
|
Buffer.size() - BlockStartPos));
|
|
|
|
auto Hash = Hasher.result();
|
|
|
|
SmallVector<uint64_t, 20> Vals;
|
|
|
|
auto LShift = [&](unsigned char Val, unsigned Amount)
|
|
|
|
-> uint64_t { return ((uint64_t)Val) << Amount; };
|
|
|
|
for (int Pos = 0; Pos < 20; Pos += 4) {
|
|
|
|
uint32_t SubHash = LShift(Hash[Pos + 0], 24);
|
|
|
|
SubHash |= LShift(Hash[Pos + 1], 16) | LShift(Hash[Pos + 2], 8) |
|
|
|
|
(unsigned)(unsigned char)Hash[Pos + 3];
|
|
|
|
Vals.push_back(SubHash);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emit the finished record.
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_HASH, Vals);
|
|
|
|
}
|
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
/// WriteModule - Emit the specified module to the bitstream.
|
2015-04-15 08:10:50 +08:00
|
|
|
static void WriteModule(const Module *M, BitstreamWriter &Stream,
|
2015-09-18 04:12:00 +08:00
|
|
|
bool ShouldPreserveUseListOrder,
|
2016-04-11 21:58:45 +08:00
|
|
|
uint64_t BitcodeStartBit,
|
|
|
|
const ModuleSummaryIndex *Index, bool GenerateHash,
|
|
|
|
SmallVectorImpl<char> &Buffer) {
|
2007-04-24 02:58:34 +08:00
|
|
|
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
|
2016-04-01 13:33:11 +08:00
|
|
|
size_t BlockStartPos = Buffer.size();
|
2009-09-20 10:20:51 +08:00
|
|
|
|
Change encoding of instruction operands in bitcode binaries to be relative
to the instruction position. The old encoding would give an absolute
ID which counts up within a function, and only resets at the next function.
I.e., Instead of having:
... = icmp eq i32 n-1, n-2
br i1 ..., label %bb1, label %bb2
it will now be roughly:
... = icmp eq i32 1, 2
br i1 1, label %bb1, label %bb2
This makes it so that ids remain relatively small and can be encoded
in fewer bits.
With this encoding, forward reference operands will be given
negative-valued IDs. Use signed VBRs for the most common case
of forward references, which is phi instructions.
To retain backward compatibility we bump the bitcode version
from 0 to 1 to distinguish between the different encodings.
llvm-svn: 165739
2012-10-12 04:20:40 +08:00
|
|
|
SmallVector<unsigned, 1> Vals;
|
|
|
|
unsigned CurVersion = 1;
|
|
|
|
Vals.push_back(CurVersion);
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
// Analyze the module, enumerating globals, functions, etc.
|
2015-04-15 08:10:50 +08:00
|
|
|
ValueEnumerator VE(*M, ShouldPreserveUseListOrder);
|
2007-05-05 15:36:14 +08:00
|
|
|
|
|
|
|
// Emit blockinfo, which defines the standard abbreviations etc.
|
|
|
|
WriteBlockInfo(VE, Stream);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2013-02-11 07:09:32 +08:00
|
|
|
// Emit information about attribute groups.
|
|
|
|
WriteAttributeGroupTable(VE, Stream);
|
|
|
|
|
2007-05-04 08:44:52 +08:00
|
|
|
// Emit information about parameter attributes.
|
2008-09-26 05:00:45 +08:00
|
|
|
WriteAttributeTable(VE, Stream);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
// Emit information describing all of the types in the module.
|
|
|
|
WriteTypeTable(VE, Stream);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2014-06-28 02:19:56 +08:00
|
|
|
writeComdats(VE, Stream);
|
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
// Emit top-level description of module, including target triple, inline asm,
|
|
|
|
// descriptors for global variables, and function prototype info.
|
2015-09-18 04:12:00 +08:00
|
|
|
uint64_t VSTOffsetPlaceholder = WriteModuleInfo(M, VE, Stream);
|
2009-07-23 01:43:22 +08:00
|
|
|
|
2009-07-23 09:07:34 +08:00
|
|
|
// Emit constants.
|
|
|
|
WriteModuleConstants(VE, Stream);
|
|
|
|
|
2009-08-04 13:01:35 +08:00
|
|
|
// Emit metadata.
|
2016-03-28 07:56:04 +08:00
|
|
|
writeModuleMetadata(*M, VE, Stream);
|
2009-08-04 13:01:35 +08:00
|
|
|
|
2009-09-19 03:26:43 +08:00
|
|
|
// Emit metadata.
|
2009-12-29 04:10:43 +08:00
|
|
|
WriteModuleMetadataStore(M, Stream);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2014-07-29 05:19:41 +08:00
|
|
|
// Emit module-level use-lists.
|
2015-04-15 07:45:11 +08:00
|
|
|
if (VE.shouldPreserveUseListOrder())
|
2014-07-29 05:19:41 +08:00
|
|
|
WriteUseListBlock(nullptr, VE, Stream);
|
2011-12-08 05:44:12 +08:00
|
|
|
|
2015-09-25 07:34:52 +08:00
|
|
|
WriteOperandBundleTags(M, Stream);
|
|
|
|
|
2012-02-07 06:30:29 +08:00
|
|
|
// Emit function bodies.
|
2016-04-11 21:58:45 +08:00
|
|
|
DenseMap<const Function *, uint64_t> FunctionToBitcodeIndex;
|
2012-02-07 06:30:29 +08:00
|
|
|
for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
|
|
|
|
if (!F->isDeclaration())
|
2016-04-11 21:58:45 +08:00
|
|
|
WriteFunction(*F, M, VE, Stream, FunctionToBitcodeIndex);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
// Need to write after the above call to WriteFunction which populates
|
|
|
|
// the summary information in the index.
|
2016-04-11 21:58:45 +08:00
|
|
|
if (Index)
|
|
|
|
WritePerModuleGlobalValueSummary(M, *Index, VE, Stream);
|
2015-09-18 04:12:00 +08:00
|
|
|
|
|
|
|
WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream,
|
2016-04-03 01:29:47 +08:00
|
|
|
VSTOffsetPlaceholder, BitcodeStartBit,
|
2016-04-11 21:58:45 +08:00
|
|
|
&FunctionToBitcodeIndex);
|
2012-02-07 06:30:29 +08:00
|
|
|
|
2016-04-01 13:33:11 +08:00
|
|
|
if (GenerateHash) {
|
|
|
|
writeModuleHash(Stream, Buffer, BlockStartPos);
|
|
|
|
}
|
|
|
|
|
2007-04-22 14:24:45 +08:00
|
|
|
Stream.ExitBlock();
|
|
|
|
}
|
|
|
|
|
2008-07-09 13:14:23 +08:00
|
|
|
/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a
|
|
|
|
/// header and trailer to make it compatible with the system archiver. To do
|
|
|
|
/// this we emit the following header, and then emit a trailer that pads the
|
|
|
|
/// file out to be a multiple of 16 bytes.
|
2009-09-20 10:20:51 +08:00
|
|
|
///
|
2008-07-09 13:14:23 +08:00
|
|
|
/// struct bc_header {
|
|
|
|
/// uint32_t Magic; // 0x0B17C0DE
|
|
|
|
/// uint32_t Version; // Version, currently always 0.
|
|
|
|
/// uint32_t BitcodeOffset; // Offset to traditional bitcode file.
|
|
|
|
/// uint32_t BitcodeSize; // Size of traditional bitcode file.
|
|
|
|
/// uint32_t CPUType; // CPU specifier.
|
|
|
|
/// ... potentially more later ...
|
|
|
|
/// };
|
|
|
|
|
2012-03-01 04:31:09 +08:00
|
|
|
static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer,
|
2012-03-01 04:31:01 +08:00
|
|
|
uint32_t &Position) {
|
2015-06-18 04:55:30 +08:00
|
|
|
support::endian::write32le(&Buffer[Position], Value);
|
2012-03-01 04:31:01 +08:00
|
|
|
Position += 4;
|
|
|
|
}
|
|
|
|
|
2012-03-01 04:31:09 +08:00
|
|
|
static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
|
2012-03-01 04:31:01 +08:00
|
|
|
const Triple &TT) {
|
2008-07-09 13:14:23 +08:00
|
|
|
unsigned CPUType = ~0U;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2010-02-13 04:13:44 +08:00
|
|
|
// Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
|
2010-02-13 04:39:35 +08:00
|
|
|
// armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic
|
|
|
|
// number from /usr/include/mach/machine.h. It is ok to reproduce the
|
|
|
|
// specific constants here because they are implicitly part of the Darwin ABI.
|
2008-07-09 13:14:23 +08:00
|
|
|
enum {
|
|
|
|
DARWIN_CPU_ARCH_ABI64 = 0x01000000,
|
|
|
|
DARWIN_CPU_TYPE_X86 = 7,
|
2010-02-13 04:13:44 +08:00
|
|
|
DARWIN_CPU_TYPE_ARM = 12,
|
2008-07-09 13:14:23 +08:00
|
|
|
DARWIN_CPU_TYPE_POWERPC = 18
|
|
|
|
};
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2011-06-14 09:51:33 +08:00
|
|
|
Triple::ArchType Arch = TT.getArch();
|
|
|
|
if (Arch == Triple::x86_64)
|
2008-07-09 13:14:23 +08:00
|
|
|
CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64;
|
2011-06-14 09:51:33 +08:00
|
|
|
else if (Arch == Triple::x86)
|
2008-07-09 13:14:23 +08:00
|
|
|
CPUType = DARWIN_CPU_TYPE_X86;
|
2011-06-14 09:51:33 +08:00
|
|
|
else if (Arch == Triple::ppc)
|
2008-07-09 13:14:23 +08:00
|
|
|
CPUType = DARWIN_CPU_TYPE_POWERPC;
|
2011-06-14 09:51:33 +08:00
|
|
|
else if (Arch == Triple::ppc64)
|
2008-07-09 13:14:23 +08:00
|
|
|
CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
|
2011-06-14 09:51:33 +08:00
|
|
|
else if (Arch == Triple::arm || Arch == Triple::thumb)
|
2010-02-13 04:13:44 +08:00
|
|
|
CPUType = DARWIN_CPU_TYPE_ARM;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2008-07-09 13:14:23 +08:00
|
|
|
// Traditional Bitcode starts after header.
|
2016-01-29 13:55:09 +08:00
|
|
|
assert(Buffer.size() >= BWH_HeaderSize &&
|
2012-03-01 04:31:01 +08:00
|
|
|
"Expected header size to be reserved");
|
2016-01-29 13:55:09 +08:00
|
|
|
unsigned BCOffset = BWH_HeaderSize;
|
|
|
|
unsigned BCSize = Buffer.size() - BWH_HeaderSize;
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2012-03-01 04:31:01 +08:00
|
|
|
// Write the magic and version.
|
|
|
|
unsigned Position = 0;
|
|
|
|
WriteInt32ToBuffer(0x0B17C0DE , Buffer, Position);
|
|
|
|
WriteInt32ToBuffer(0 , Buffer, Position); // Version.
|
|
|
|
WriteInt32ToBuffer(BCOffset , Buffer, Position);
|
|
|
|
WriteInt32ToBuffer(BCSize , Buffer, Position);
|
|
|
|
WriteInt32ToBuffer(CPUType , Buffer, Position);
|
2009-09-20 10:20:51 +08:00
|
|
|
|
2008-07-09 13:14:23 +08:00
|
|
|
// If the file is not a multiple of 16 bytes, insert dummy padding.
|
2012-03-01 04:31:01 +08:00
|
|
|
while (Buffer.size() & 15)
|
|
|
|
Buffer.push_back(0);
|
2008-07-09 13:14:23 +08:00
|
|
|
}
|
|
|
|
|
2015-10-04 22:33:43 +08:00
|
|
|
/// Helper to write the header common to all bitcode files.
|
|
|
|
static void WriteBitcodeHeader(BitstreamWriter &Stream) {
|
|
|
|
// Emit the file header.
|
|
|
|
Stream.Emit((unsigned)'B', 8);
|
|
|
|
Stream.Emit((unsigned)'C', 8);
|
|
|
|
Stream.Emit(0x0, 4);
|
|
|
|
Stream.Emit(0xC, 4);
|
|
|
|
Stream.Emit(0xE, 4);
|
|
|
|
Stream.Emit(0xD, 4);
|
|
|
|
}
|
|
|
|
|
2008-10-23 01:39:14 +08:00
|
|
|
/// WriteBitcodeToFile - Write the specified module to the specified output
|
|
|
|
/// stream.
|
2015-04-15 08:10:50 +08:00
|
|
|
void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
|
2015-10-04 22:33:43 +08:00
|
|
|
bool ShouldPreserveUseListOrder,
|
2016-04-11 21:58:45 +08:00
|
|
|
const ModuleSummaryIndex *Index,
|
|
|
|
bool GenerateHash) {
|
2012-12-04 05:29:36 +08:00
|
|
|
SmallVector<char, 0> Buffer;
|
2007-04-22 14:24:45 +08:00
|
|
|
Buffer.reserve(256*1024);
|
2008-12-20 02:37:59 +08:00
|
|
|
|
2012-03-01 04:31:01 +08:00
|
|
|
// If this is darwin or another generic macho target, reserve space for the
|
|
|
|
// header.
|
2011-06-14 09:51:33 +08:00
|
|
|
Triple TT(M->getTargetTriple());
|
2016-01-24 00:02:10 +08:00
|
|
|
if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
|
2016-01-29 13:55:09 +08:00
|
|
|
Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0);
|
2012-03-01 04:31:01 +08:00
|
|
|
|
|
|
|
// Emit the module into the buffer.
|
|
|
|
{
|
|
|
|
BitstreamWriter Stream(Buffer);
|
2015-09-18 04:12:00 +08:00
|
|
|
// Save the start bit of the actual bitcode, in case there is space
|
|
|
|
// saved at the start for the darwin header above. The reader stream
|
|
|
|
// will start at the bitcode, and we need the offset of the VST
|
|
|
|
// to line up.
|
|
|
|
uint64_t BitcodeStartBit = Stream.GetCurrentBitNo();
|
2012-03-01 04:31:01 +08:00
|
|
|
|
|
|
|
// Emit the file header.
|
2015-10-04 22:33:43 +08:00
|
|
|
WriteBitcodeHeader(Stream);
|
2012-03-01 04:31:01 +08:00
|
|
|
|
2015-10-27 02:37:00 +08:00
|
|
|
WriteIdentificationBlock(M, Stream);
|
|
|
|
|
2012-03-01 04:31:01 +08:00
|
|
|
// Emit the module.
|
2016-04-11 21:58:45 +08:00
|
|
|
WriteModule(M, Stream, ShouldPreserveUseListOrder, BitcodeStartBit, Index,
|
|
|
|
GenerateHash, Buffer);
|
2012-03-01 04:31:01 +08:00
|
|
|
}
|
2008-07-09 13:14:23 +08:00
|
|
|
|
2016-01-24 00:02:10 +08:00
|
|
|
if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
|
2012-03-01 04:31:01 +08:00
|
|
|
EmitDarwinBCHeaderAndTrailer(Buffer, TT);
|
|
|
|
|
|
|
|
// Write the generated bitstream to "Out".
|
|
|
|
Out.write((char*)&Buffer.front(), Buffer.size());
|
2007-04-22 14:24:45 +08:00
|
|
|
}
|
2015-10-04 22:33:43 +08:00
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Write the specified module summary index to the given raw output stream,
|
2015-10-04 22:33:43 +08:00
|
|
|
// where it will be written in a new bitcode block. This is used when
|
|
|
|
// writing the combined index file for ThinLTO.
|
2016-03-15 08:04:37 +08:00
|
|
|
void llvm::WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out) {
|
2015-10-04 22:33:43 +08:00
|
|
|
SmallVector<char, 0> Buffer;
|
|
|
|
Buffer.reserve(256 * 1024);
|
|
|
|
|
|
|
|
BitstreamWriter Stream(Buffer);
|
|
|
|
|
|
|
|
// Emit the bitcode header.
|
|
|
|
WriteBitcodeHeader(Stream);
|
|
|
|
|
|
|
|
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
|
|
|
|
|
|
|
|
SmallVector<unsigned, 1> Vals;
|
|
|
|
unsigned CurVersion = 1;
|
|
|
|
Vals.push_back(CurVersion);
|
|
|
|
Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
|
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// If we have a VST, write the VSTOFFSET record placeholder and record
|
|
|
|
// its offset.
|
|
|
|
uint64_t VSTOffsetPlaceholder = WriteValueSymbolTableForwardDecl(Stream);
|
|
|
|
|
2015-10-04 22:33:43 +08:00
|
|
|
// Write the module paths in the combined index.
|
|
|
|
WriteModStrings(Index, Stream);
|
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Assign unique value ids to all functions in the index for use
|
|
|
|
// in writing out the call graph edges. Save the mapping from GUID
|
|
|
|
// to the new global value id to use when writing those edges, which
|
|
|
|
// are currently saved in the index in terms of GUID.
|
2016-04-02 13:07:53 +08:00
|
|
|
std::map<GlobalValue::GUID, unsigned> GUIDToValueIdMap;
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
unsigned GlobalValueId = 0;
|
|
|
|
for (auto &II : Index)
|
|
|
|
GUIDToValueIdMap[II.first] = ++GlobalValueId;
|
|
|
|
|
|
|
|
// Write the summary combined index records.
|
|
|
|
WriteCombinedGlobalValueSummary(Index, Stream, GUIDToValueIdMap,
|
|
|
|
GlobalValueId);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
// Need a special VST writer for the combined index (we don't have a
|
|
|
|
// real VST and real values when this is invoked).
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
WriteCombinedValueSymbolTable(Index, Stream, GUIDToValueIdMap,
|
|
|
|
VSTOffsetPlaceholder);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
Stream.ExitBlock();
|
|
|
|
|
|
|
|
Out.write((char *)&Buffer.front(), Buffer.size());
|
|
|
|
}
|