2012-12-27 06:00:49 +08:00
|
|
|
//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
|
2009-06-30 08:48:55 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2009-06-30 08:48:55 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2009-07-01 01:06:46 +08:00
|
|
|
//
|
|
|
|
// This file implements LLVMContext, as a wrapper around the opaque
|
2009-08-12 01:45:13 +08:00
|
|
|
// class LLVMContextImpl.
|
2009-07-01 01:06:46 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2009-06-30 08:48:55 +08:00
|
|
|
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/LLVMContext.h"
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "LLVMContextImpl.h"
|
2016-04-29 02:04:41 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
#include "llvm/ADT/Twine.h"
|
2013-12-18 01:47:22 +08:00
|
|
|
#include "llvm/IR/DiagnosticInfo.h"
|
|
|
|
#include "llvm/IR/DiagnosticPrinter.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Metadata.h"
|
2016-04-29 02:04:41 +08:00
|
|
|
#include "llvm/IR/Module.h"
|
2019-03-06 23:20:13 +08:00
|
|
|
#include "llvm/IR/RemarkStreamer.h"
|
2016-04-29 02:04:41 +08:00
|
|
|
#include "llvm/Support/Casting.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <string>
|
|
|
|
#include <utility>
|
|
|
|
|
2009-06-30 08:48:55 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2010-03-31 07:03:27 +08:00
|
|
|
LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
|
2010-09-15 05:25:10 +08:00
|
|
|
// Create the fixed metadata kinds. This is done in the same order as the
|
|
|
|
// MD_* enum values so that they correspond.
|
2016-12-07 07:53:01 +08:00
|
|
|
std::pair<unsigned, StringRef> MDKinds[] = {
|
|
|
|
{MD_dbg, "dbg"},
|
|
|
|
{MD_tbaa, "tbaa"},
|
|
|
|
{MD_prof, "prof"},
|
|
|
|
{MD_fpmath, "fpmath"},
|
|
|
|
{MD_range, "range"},
|
|
|
|
{MD_tbaa_struct, "tbaa.struct"},
|
|
|
|
{MD_invariant_load, "invariant.load"},
|
|
|
|
{MD_alias_scope, "alias.scope"},
|
|
|
|
{MD_noalias, "noalias"},
|
|
|
|
{MD_nontemporal, "nontemporal"},
|
|
|
|
{MD_mem_parallel_loop_access, "llvm.mem.parallel_loop_access"},
|
|
|
|
{MD_nonnull, "nonnull"},
|
|
|
|
{MD_dereferenceable, "dereferenceable"},
|
|
|
|
{MD_dereferenceable_or_null, "dereferenceable_or_null"},
|
|
|
|
{MD_make_implicit, "make.implicit"},
|
|
|
|
{MD_unpredictable, "unpredictable"},
|
|
|
|
{MD_invariant_group, "invariant.group"},
|
|
|
|
{MD_align, "align"},
|
|
|
|
{MD_loop, "llvm.loop"},
|
|
|
|
{MD_type, "type"},
|
|
|
|
{MD_section_prefix, "section_prefix"},
|
2016-12-09 03:01:00 +08:00
|
|
|
{MD_absolute_symbol, "absolute_symbol"},
|
2017-03-18 06:17:24 +08:00
|
|
|
{MD_associated, "associated"},
|
2017-10-17 06:22:11 +08:00
|
|
|
{MD_callees, "callees"},
|
2017-11-03 06:26:51 +08:00
|
|
|
{MD_irr_loop, "irr_loop"},
|
2018-12-20 12:58:07 +08:00
|
|
|
{MD_access_group, "llvm.access.group"},
|
AbstractCallSite -- A unified interface for (in)direct and callback calls
An abstract call site is a wrapper that allows to treat direct,
indirect, and callback calls the same. If an abstract call site
represents a direct or indirect call site it behaves like a stripped
down version of a normal call site object. The abstract call site can
also represent a callback call, thus the fact that the initially
called function (=broker) may invoke a third one (=callback callee).
In this case, the abstract call side hides the middle man, hence the
broker function. The result is a representation of the callback call,
inside the broker, but in the context of the original instruction that
invoked the broker.
Again, there are up to three functions involved when we talk about
callback call sites. The caller (1), which invokes the broker
function. The broker function (2), that may or may not invoke the
callback callee. And finally the callback callee (3), which is the
target of the callback call.
The abstract call site will handle the mapping from parameters to
arguments depending on the semantic of the broker function. However,
it is important to note that the mapping is often partial. Thus, some
arguments of the call/invoke instruction are mapped to parameters of
the callee while others are not. At the same time, arguments of the
callback callee might be unknown, thus "null" if queried.
This patch introduces also !callback metadata which describe how a
callback broker maps from parameters to arguments. This metadata is
directly created by clang for known broker functions, provided through
source code attributes by the user, or later deduced by analyses.
For motivation and additional information please see the corresponding
talk (slides/video)
https://llvm.org/devmtg/2018-10/talk-abstracts.html#talk20
as well as the LCPC paper
http://compilers.cs.uni-saarland.de/people/doerfert/par_opt_lcpc18.pdf
Differential Revision: https://reviews.llvm.org/D54498
llvm-svn: 351627
2019-01-19 13:19:06 +08:00
|
|
|
{MD_callback, "callback"},
|
2016-12-07 07:53:01 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
for (auto &MDKind : MDKinds) {
|
|
|
|
unsigned ID = getMDKindID(MDKind.second);
|
|
|
|
assert(ID == MDKind.first && "metadata kind id drifted");
|
|
|
|
(void)ID;
|
|
|
|
}
|
2016-10-19 04:42:47 +08:00
|
|
|
|
2015-11-12 05:38:02 +08:00
|
|
|
auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
|
|
|
|
assert(DeoptEntry->second == LLVMContext::OB_deopt &&
|
|
|
|
"deopt operand bundle id drifted!");
|
|
|
|
(void)DeoptEntry;
|
2015-12-16 05:27:27 +08:00
|
|
|
|
|
|
|
auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
|
|
|
|
assert(FuncletEntry->second == LLVMContext::OB_funclet &&
|
|
|
|
"funclet operand bundle id drifted!");
|
|
|
|
(void)FuncletEntry;
|
2016-01-21 03:50:25 +08:00
|
|
|
|
|
|
|
auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
|
|
|
|
assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&
|
|
|
|
"gc-transition operand bundle id drifted!");
|
|
|
|
(void)GCTransitionEntry;
|
2017-07-12 06:23:00 +08:00
|
|
|
|
|
|
|
SyncScope::ID SingleThreadSSID =
|
|
|
|
pImpl->getOrInsertSyncScopeID("singlethread");
|
|
|
|
assert(SingleThreadSSID == SyncScope::SingleThread &&
|
|
|
|
"singlethread synchronization scope ID drifted!");
|
2017-07-12 08:15:53 +08:00
|
|
|
(void)SingleThreadSSID;
|
2017-07-12 06:23:00 +08:00
|
|
|
|
|
|
|
SyncScope::ID SystemSSID =
|
|
|
|
pImpl->getOrInsertSyncScopeID("");
|
|
|
|
assert(SystemSSID == SyncScope::System &&
|
|
|
|
"system synchronization scope ID drifted!");
|
2017-07-12 08:15:53 +08:00
|
|
|
(void)SystemSSID;
|
2010-03-31 07:03:27 +08:00
|
|
|
}
|
2016-04-29 02:04:41 +08:00
|
|
|
|
2009-06-30 08:48:55 +08:00
|
|
|
LLVMContext::~LLVMContext() { delete pImpl; }
|
2009-08-05 06:41:48 +08:00
|
|
|
|
2010-09-09 02:03:32 +08:00
|
|
|
void LLVMContext::addModule(Module *M) {
|
|
|
|
pImpl->OwnedModules.insert(M);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMContext::removeModule(Module *M) {
|
|
|
|
pImpl->OwnedModules.erase(M);
|
|
|
|
}
|
|
|
|
|
introduce a new recoverable error handling API to LLVMContext
and use it in one place in inline asm handling stuff. Before
we'd generate this for an invalid modifier letter:
$ clang asm.c -c -o t.o
fatal error: error in backend: Invalid operand found in inline asm: 'abc incl ${0:Z}'
INLINEASM <es:abc incl ${0:Z}>, 10, %EAX<def>, 2147483657, %EAX, 14, %EFLAGS<earlyclobber,def,dead>, <!-1>
Now we generate this:
$ clang asm.c -c -o t.o
error: invalid operand in inline asm: 'incl ${0:Z}'
asm.c:3:12: note: generated from here
__asm__ ("incl %Z0" : "+r" (X));
^
1 error generated.
This is much better but still admittedly not great ("why" is the operand
invalid??), codegen should try harder with its diagnostics :)
llvm-svn: 100723
2010-04-08 07:40:44 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Recoverable Backend Errors
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-02-11 13:37:07 +08:00
|
|
|
void LLVMContext::
|
|
|
|
setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
|
|
|
|
void *DiagContext) {
|
|
|
|
pImpl->InlineAsmDiagHandler = DiagHandler;
|
|
|
|
pImpl->InlineAsmDiagContext = DiagContext;
|
2010-04-06 08:44:45 +08:00
|
|
|
}
|
|
|
|
|
2013-02-11 13:37:07 +08:00
|
|
|
/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
|
|
|
|
/// setInlineAsmDiagnosticHandler.
|
|
|
|
LLVMContext::InlineAsmDiagHandlerTy
|
|
|
|
LLVMContext::getInlineAsmDiagnosticHandler() const {
|
|
|
|
return pImpl->InlineAsmDiagHandler;
|
2010-04-06 08:44:45 +08:00
|
|
|
}
|
|
|
|
|
2013-02-11 13:37:07 +08:00
|
|
|
/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
|
|
|
|
/// setInlineAsmDiagnosticHandler.
|
|
|
|
void *LLVMContext::getInlineAsmDiagnosticContext() const {
|
|
|
|
return pImpl->InlineAsmDiagContext;
|
2010-04-06 08:44:45 +08:00
|
|
|
}
|
2010-03-31 04:48:48 +08:00
|
|
|
|
2017-09-16 04:10:09 +08:00
|
|
|
void LLVMContext::setDiagnosticHandlerCallBack(
|
|
|
|
DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
|
|
|
|
void *DiagnosticContext, bool RespectFilters) {
|
|
|
|
pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
|
|
|
|
pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
|
|
|
|
pImpl->RespectDiagnosticFilters = RespectFilters;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
|
|
|
|
bool RespectFilters) {
|
|
|
|
pImpl->DiagHandler = std::move(DH);
|
2014-10-02 02:36:03 +08:00
|
|
|
pImpl->RespectDiagnosticFilters = RespectFilters;
|
2013-12-18 01:47:22 +08:00
|
|
|
}
|
|
|
|
|
[ORE] Unify spelling as "diagnostics hotness"
Summary:
To enable profile hotness information in diagnostics output, Clang takes
the option `-fdiagnostics-show-hotness` -- that's "diagnostics", with an
"s" at the end. Clang also defines `CodeGenOptions::DiagnosticsWithHotness`.
LLVM, on the other hand, defines
`LLVMContext::getDiagnosticHotnessRequested` -- that's "diagnostic", not
"diagnostics". It's a small difference, but it's confusing, typo-inducing, and
frustrating.
Add a new method with the spelling "diagnostics", and "deprecate" the
old spelling.
Reviewers: anemet, davidxl
Reviewed By: anemet
Subscribers: llvm-commits, mehdi_amini
Differential Revision: https://reviews.llvm.org/D34864
llvm-svn: 306848
2017-07-01 02:13:59 +08:00
|
|
|
void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {
|
|
|
|
pImpl->DiagnosticsHotnessRequested = Requested;
|
|
|
|
}
|
|
|
|
bool LLVMContext::getDiagnosticsHotnessRequested() const {
|
|
|
|
return pImpl->DiagnosticsHotnessRequested;
|
2016-07-16 01:23:20 +08:00
|
|
|
}
|
|
|
|
|
2017-07-01 07:14:53 +08:00
|
|
|
void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) {
|
|
|
|
pImpl->DiagnosticsHotnessThreshold = Threshold;
|
|
|
|
}
|
|
|
|
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
|
|
|
|
return pImpl->DiagnosticsHotnessThreshold;
|
|
|
|
}
|
|
|
|
|
2019-03-06 23:20:13 +08:00
|
|
|
RemarkStreamer *LLVMContext::getRemarkStreamer() {
|
|
|
|
return pImpl->RemarkDiagStreamer.get();
|
Output optimization remarks in YAML
(Re-committed after moving the template specialization under the yaml
namespace. GCC was complaining about this.)
This allows various presentation of this data using an external tool.
This was first recommended here[1].
As an example, consider this module:
1 int foo();
2 int bar();
3
4 int baz() {
5 return foo() + bar();
6 }
The inliner generates these missed-optimization remarks today (the
hotness information is pulled from PGO):
remark: /tmp/s.c:5:10: foo will not be inlined into baz (hotness: 30)
remark: /tmp/s.c:5:18: bar will not be inlined into baz (hotness: 30)
Now with -pass-remarks-output=<yaml-file>, we generate this YAML file:
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 10 }
Function: baz
Hotness: 30
Args:
- Callee: foo
- String: will not be inlined into
- Caller: baz
...
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 18 }
Function: baz
Hotness: 30
Args:
- Callee: bar
- String: will not be inlined into
- Caller: baz
...
This is a summary of the high-level decisions:
* There is a new streaming interface to emit optimization remarks.
E.g. for the inliner remark above:
ORE.emit(DiagnosticInfoOptimizationRemarkMissed(
DEBUG_TYPE, "NotInlined", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller()) << setIsVerbose());
NV stands for named value and allows the YAML client to process a remark
using its name (NotInlined) and the named arguments (Callee and Caller)
without parsing the text of the message.
Subsequent patches will update ORE users to use the new streaming API.
* I am using YAML I/O for writing the YAML file. YAML I/O requires you
to specify reading and writing at once but reading is highly non-trivial
for some of the more complex LLVM types. Since it's not clear that we
(ever) want to use LLVM to parse this YAML file, the code supports and
asserts that we're writing only.
On the other hand, I did experiment that the class hierarchy starting at
DiagnosticInfoOptimizationBase can be mapped back from YAML generated
here (see D24479).
* The YAML stream is stored in the LLVM context.
* In the example, we can probably further specify the IR value used,
i.e. print "Function" rather than "Value".
* As before hotness is computed in the analysis pass instead of
DiganosticInfo. This avoids the layering problem since BFI is in
Analysis while DiagnosticInfo is in IR.
[1] https://reviews.llvm.org/D19678#419445
Differential Revision: https://reviews.llvm.org/D24587
llvm-svn: 282539
2016-09-28 04:55:07 +08:00
|
|
|
}
|
2019-03-06 23:20:13 +08:00
|
|
|
const RemarkStreamer *LLVMContext::getRemarkStreamer() const {
|
|
|
|
return const_cast<LLVMContext *>(this)->getRemarkStreamer();
|
|
|
|
}
|
|
|
|
void LLVMContext::setRemarkStreamer(
|
|
|
|
std::unique_ptr<RemarkStreamer> RemarkStreamer) {
|
|
|
|
pImpl->RemarkDiagStreamer = std::move(RemarkStreamer);
|
Output optimization remarks in YAML
(Re-committed after moving the template specialization under the yaml
namespace. GCC was complaining about this.)
This allows various presentation of this data using an external tool.
This was first recommended here[1].
As an example, consider this module:
1 int foo();
2 int bar();
3
4 int baz() {
5 return foo() + bar();
6 }
The inliner generates these missed-optimization remarks today (the
hotness information is pulled from PGO):
remark: /tmp/s.c:5:10: foo will not be inlined into baz (hotness: 30)
remark: /tmp/s.c:5:18: bar will not be inlined into baz (hotness: 30)
Now with -pass-remarks-output=<yaml-file>, we generate this YAML file:
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 10 }
Function: baz
Hotness: 30
Args:
- Callee: foo
- String: will not be inlined into
- Caller: baz
...
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 18 }
Function: baz
Hotness: 30
Args:
- Callee: bar
- String: will not be inlined into
- Caller: baz
...
This is a summary of the high-level decisions:
* There is a new streaming interface to emit optimization remarks.
E.g. for the inliner remark above:
ORE.emit(DiagnosticInfoOptimizationRemarkMissed(
DEBUG_TYPE, "NotInlined", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller()) << setIsVerbose());
NV stands for named value and allows the YAML client to process a remark
using its name (NotInlined) and the named arguments (Callee and Caller)
without parsing the text of the message.
Subsequent patches will update ORE users to use the new streaming API.
* I am using YAML I/O for writing the YAML file. YAML I/O requires you
to specify reading and writing at once but reading is highly non-trivial
for some of the more complex LLVM types. Since it's not clear that we
(ever) want to use LLVM to parse this YAML file, the code supports and
asserts that we're writing only.
On the other hand, I did experiment that the class hierarchy starting at
DiagnosticInfoOptimizationBase can be mapped back from YAML generated
here (see D24479).
* The YAML stream is stored in the LLVM context.
* In the example, we can probably further specify the IR value used,
i.e. print "Function" rather than "Value".
* As before hotness is computed in the analysis pass instead of
DiganosticInfo. This avoids the layering problem since BFI is in
Analysis while DiagnosticInfo is in IR.
[1] https://reviews.llvm.org/D19678#419445
Differential Revision: https://reviews.llvm.org/D24587
llvm-svn: 282539
2016-09-28 04:55:07 +08:00
|
|
|
}
|
|
|
|
|
2017-09-16 04:10:09 +08:00
|
|
|
DiagnosticHandler::DiagnosticHandlerTy
|
|
|
|
LLVMContext::getDiagnosticHandlerCallBack() const {
|
|
|
|
return pImpl->DiagHandler->DiagHandlerCallback;
|
2013-12-18 01:47:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void *LLVMContext::getDiagnosticContext() const {
|
2017-09-16 04:10:09 +08:00
|
|
|
return pImpl->DiagHandler->DiagnosticContext;
|
2013-12-18 01:47:22 +08:00
|
|
|
}
|
|
|
|
|
2014-05-16 10:33:15 +08:00
|
|
|
void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
|
|
|
|
{
|
|
|
|
pImpl->YieldCallback = Callback;
|
|
|
|
pImpl->YieldOpaqueHandle = OpaqueHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMContext::yield() {
|
|
|
|
if (pImpl->YieldCallback)
|
|
|
|
pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
|
|
|
|
}
|
|
|
|
|
2012-01-04 07:47:05 +08:00
|
|
|
void LLVMContext::emitError(const Twine &ErrorStr) {
|
2014-02-22 08:34:11 +08:00
|
|
|
diagnose(DiagnosticInfoInlineAsm(ErrorStr));
|
introduce a new recoverable error handling API to LLVMContext
and use it in one place in inline asm handling stuff. Before
we'd generate this for an invalid modifier letter:
$ clang asm.c -c -o t.o
fatal error: error in backend: Invalid operand found in inline asm: 'abc incl ${0:Z}'
INLINEASM <es:abc incl ${0:Z}>, 10, %EAX<def>, 2147483657, %EAX, 14, %EFLAGS<earlyclobber,def,dead>, <!-1>
Now we generate this:
$ clang asm.c -c -o t.o
error: invalid operand in inline asm: 'incl ${0:Z}'
asm.c:3:12: note: generated from here
__asm__ ("incl %Z0" : "+r" (X));
^
1 error generated.
This is much better but still admittedly not great ("why" is the operand
invalid??), codegen should try harder with its diagnostics :)
llvm-svn: 100723
2010-04-08 07:40:44 +08:00
|
|
|
}
|
|
|
|
|
2013-02-09 05:48:29 +08:00
|
|
|
void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
|
2014-02-22 08:34:11 +08:00
|
|
|
assert (I && "Invalid instruction");
|
|
|
|
diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
|
introduce a new recoverable error handling API to LLVMContext
and use it in one place in inline asm handling stuff. Before
we'd generate this for an invalid modifier letter:
$ clang asm.c -c -o t.o
fatal error: error in backend: Invalid operand found in inline asm: 'abc incl ${0:Z}'
INLINEASM <es:abc incl ${0:Z}>, 10, %EAX<def>, 2147483657, %EAX, 14, %EFLAGS<earlyclobber,def,dead>, <!-1>
Now we generate this:
$ clang asm.c -c -o t.o
error: invalid operand in inline asm: 'incl ${0:Z}'
asm.c:3:12: note: generated from here
__asm__ ("incl %Z0" : "+r" (X));
^
1 error generated.
This is much better but still admittedly not great ("why" is the operand
invalid??), codegen should try harder with its diagnostics :)
llvm-svn: 100723
2010-04-08 07:40:44 +08:00
|
|
|
}
|
|
|
|
|
2014-10-02 02:36:03 +08:00
|
|
|
static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
|
2014-05-22 22:19:46 +08:00
|
|
|
// Optimization remarks are selective. They need to check whether the regexp
|
|
|
|
// pattern, passed via one of the -pass-remarks* flags, matches the name of
|
|
|
|
// the pass that is emitting the diagnostic. If there is no match, ignore the
|
|
|
|
// diagnostic and return.
|
2017-10-04 12:26:23 +08:00
|
|
|
//
|
|
|
|
// Also noisy remarks are only enabled if we have hotness information to sort
|
|
|
|
// them.
|
2016-04-01 08:34:39 +08:00
|
|
|
if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
|
2017-10-04 12:26:23 +08:00
|
|
|
return Remark->isEnabled() &&
|
|
|
|
(!Remark->isVerbose() || Remark->getHotness());
|
2016-04-01 08:34:39 +08:00
|
|
|
|
2014-10-02 02:36:03 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-16 22:28:02 +08:00
|
|
|
const char *
|
|
|
|
LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
|
2015-06-16 04:30:22 +08:00
|
|
|
switch (Severity) {
|
|
|
|
case DS_Error:
|
|
|
|
return "error";
|
|
|
|
case DS_Warning:
|
|
|
|
return "warning";
|
|
|
|
case DS_Remark:
|
|
|
|
return "remark";
|
|
|
|
case DS_Note:
|
|
|
|
return "note";
|
|
|
|
}
|
2015-06-16 21:14:59 +08:00
|
|
|
llvm_unreachable("Unknown DiagnosticSeverity");
|
2015-06-16 04:30:22 +08:00
|
|
|
}
|
|
|
|
|
2014-10-02 02:36:03 +08:00
|
|
|
void LLVMContext::diagnose(const DiagnosticInfo &DI) {
|
2019-03-06 23:20:13 +08:00
|
|
|
if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
|
|
|
|
if (RemarkStreamer *RS = getRemarkStreamer())
|
|
|
|
RS->emit(*OptDiagBase);
|
|
|
|
|
2014-10-02 02:36:03 +08:00
|
|
|
// If there is a report handler, use it.
|
2017-09-16 04:10:09 +08:00
|
|
|
if (pImpl->DiagHandler &&
|
|
|
|
(!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
|
|
|
|
pImpl->DiagHandler->handleDiagnostics(DI))
|
2014-10-02 02:36:03 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!isDiagnosticEnabled(DI))
|
|
|
|
return;
|
2014-04-17 00:53:41 +08:00
|
|
|
|
2013-12-18 01:47:22 +08:00
|
|
|
// Otherwise, print the message with a prefix based on the severity.
|
2015-06-16 04:30:22 +08:00
|
|
|
DiagnosticPrinterRawOStream DP(errs());
|
|
|
|
errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
|
2013-12-18 01:47:22 +08:00
|
|
|
DI.print(DP);
|
2015-06-16 04:30:22 +08:00
|
|
|
errs() << "\n";
|
|
|
|
if (DI.getSeverity() == DS_Error)
|
2013-12-18 01:47:22 +08:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-01-04 07:47:05 +08:00
|
|
|
void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
|
2014-02-22 08:34:11 +08:00
|
|
|
diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
|
introduce a new recoverable error handling API to LLVMContext
and use it in one place in inline asm handling stuff. Before
we'd generate this for an invalid modifier letter:
$ clang asm.c -c -o t.o
fatal error: error in backend: Invalid operand found in inline asm: 'abc incl ${0:Z}'
INLINEASM <es:abc incl ${0:Z}>, 10, %EAX<def>, 2147483657, %EAX, 14, %EFLAGS<earlyclobber,def,dead>, <!-1>
Now we generate this:
$ clang asm.c -c -o t.o
error: invalid operand in inline asm: 'incl ${0:Z}'
asm.c:3:12: note: generated from here
__asm__ ("incl %Z0" : "+r" (X));
^
1 error generated.
This is much better but still admittedly not great ("why" is the operand
invalid??), codegen should try harder with its diagnostics :)
llvm-svn: 100723
2010-04-08 07:40:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Metadata Kind Uniquing
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-06-03 05:25:00 +08:00
|
|
|
/// Return a unique non-zero ID for the specified metadata kind.
|
2010-03-31 04:48:48 +08:00
|
|
|
unsigned LLVMContext::getMDKindID(StringRef Name) const {
|
|
|
|
// If this is new, assign it its ID.
|
2015-06-03 05:25:00 +08:00
|
|
|
return pImpl->CustomMDKindNames.insert(
|
|
|
|
std::make_pair(
|
|
|
|
Name, pImpl->CustomMDKindNames.size()))
|
2014-11-19 13:49:42 +08:00
|
|
|
.first->second;
|
2009-08-05 06:41:48 +08:00
|
|
|
}
|
2009-08-11 14:31:57 +08:00
|
|
|
|
2015-08-25 07:20:16 +08:00
|
|
|
/// getHandlerNames - Populate client-supplied smallvector using custom
|
2010-03-31 04:48:48 +08:00
|
|
|
/// metadata name and ID.
|
|
|
|
void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
|
2010-07-21 05:42:28 +08:00
|
|
|
Names.resize(pImpl->CustomMDKindNames.size());
|
2010-03-31 04:48:48 +08:00
|
|
|
for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
|
|
|
|
E = pImpl->CustomMDKindNames.end(); I != E; ++I)
|
|
|
|
Names[I->second] = I->first();
|
|
|
|
}
|
2015-09-25 03:14:18 +08:00
|
|
|
|
|
|
|
void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
|
|
|
|
pImpl->getOperandBundleTags(Tags);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
|
|
|
|
return pImpl->getOperandBundleTagID(Tag);
|
|
|
|
}
|
2016-01-08 10:28:20 +08:00
|
|
|
|
2017-07-12 06:23:00 +08:00
|
|
|
SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) {
|
|
|
|
return pImpl->getOrInsertSyncScopeID(SSN);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const {
|
|
|
|
pImpl->getSyncScopeNames(SSNs);
|
|
|
|
}
|
|
|
|
|
2016-01-08 10:28:20 +08:00
|
|
|
void LLVMContext::setGC(const Function &Fn, std::string GCName) {
|
|
|
|
auto It = pImpl->GCNames.find(&Fn);
|
|
|
|
|
|
|
|
if (It == pImpl->GCNames.end()) {
|
|
|
|
pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
It->second = std::move(GCName);
|
|
|
|
}
|
2016-04-29 02:04:41 +08:00
|
|
|
|
2016-01-08 10:28:20 +08:00
|
|
|
const std::string &LLVMContext::getGC(const Function &Fn) {
|
|
|
|
return pImpl->GCNames[&Fn];
|
|
|
|
}
|
2016-04-29 02:04:41 +08:00
|
|
|
|
2016-01-08 10:28:20 +08:00
|
|
|
void LLVMContext::deleteGC(const Function &Fn) {
|
|
|
|
pImpl->GCNames.erase(&Fn);
|
|
|
|
}
|
Add a flag to the LLVMContext to disable name for Value other than GlobalValue
Summary:
This is intended to be a performance flag, on the same level as clang
cc1 option "--disable-free". LLVM will never initialize it by default,
it will be up to the client creating the LLVMContext to request this
behavior. Clang will do it by default in Release build (just like
--disable-free).
"opt" and "llc" can opt-in using -disable-named-value command line
option.
When performing LTO on llvm-tblgen, the initial merging of IR peaks
at 92MB without this patch, and 86MB after this patch,setNameImpl()
drops from 6.5MB to 0.5MB.
The total link time goes from ~29.5s to ~27.8s.
Compared to a compile-time flag (like the IRBuilder one), it performs
very close. I profiled on SROA and obtain these results:
420ms with IRBuilder that preserve name
372ms with IRBuilder that strip name
375ms with IRBuilder that preserve name, and a runtime flag to strip
Reviewers: chandlerc, dexonsmith, bogner
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17946
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 263086
2016-03-10 09:28:54 +08:00
|
|
|
|
2016-04-02 11:59:58 +08:00
|
|
|
bool LLVMContext::shouldDiscardValueNames() const {
|
|
|
|
return pImpl->DiscardValueNames;
|
|
|
|
}
|
Add a flag to the LLVMContext to disable name for Value other than GlobalValue
Summary:
This is intended to be a performance flag, on the same level as clang
cc1 option "--disable-free". LLVM will never initialize it by default,
it will be up to the client creating the LLVMContext to request this
behavior. Clang will do it by default in Release build (just like
--disable-free).
"opt" and "llc" can opt-in using -disable-named-value command line
option.
When performing LTO on llvm-tblgen, the initial merging of IR peaks
at 92MB without this patch, and 86MB after this patch,setNameImpl()
drops from 6.5MB to 0.5MB.
The total link time goes from ~29.5s to ~27.8s.
Compared to a compile-time flag (like the IRBuilder one), it performs
very close. I profiled on SROA and obtain these results:
420ms with IRBuilder that preserve name
372ms with IRBuilder that strip name
375ms with IRBuilder that preserve name, and a runtime flag to strip
Reviewers: chandlerc, dexonsmith, bogner
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17946
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 263086
2016-03-10 09:28:54 +08:00
|
|
|
|
2016-04-19 12:55:25 +08:00
|
|
|
bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }
|
2016-04-17 11:58:21 +08:00
|
|
|
|
2016-04-19 12:55:25 +08:00
|
|
|
void LLVMContext::enableDebugTypeODRUniquing() {
|
2016-04-17 11:58:21 +08:00
|
|
|
if (pImpl->DITypeMap)
|
|
|
|
return;
|
|
|
|
|
2016-04-20 00:06:50 +08:00
|
|
|
pImpl->DITypeMap.emplace();
|
2016-04-17 11:58:21 +08:00
|
|
|
}
|
|
|
|
|
2016-04-19 12:55:25 +08:00
|
|
|
void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
|
2016-04-17 11:58:21 +08:00
|
|
|
|
Add a flag to the LLVMContext to disable name for Value other than GlobalValue
Summary:
This is intended to be a performance flag, on the same level as clang
cc1 option "--disable-free". LLVM will never initialize it by default,
it will be up to the client creating the LLVMContext to request this
behavior. Clang will do it by default in Release build (just like
--disable-free).
"opt" and "llc" can opt-in using -disable-named-value command line
option.
When performing LTO on llvm-tblgen, the initial merging of IR peaks
at 92MB without this patch, and 86MB after this patch,setNameImpl()
drops from 6.5MB to 0.5MB.
The total link time goes from ~29.5s to ~27.8s.
Compared to a compile-time flag (like the IRBuilder one), it performs
very close. I profiled on SROA and obtain these results:
420ms with IRBuilder that preserve name
372ms with IRBuilder that strip name
375ms with IRBuilder that preserve name, and a runtime flag to strip
Reviewers: chandlerc, dexonsmith, bogner
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17946
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 263086
2016-03-10 09:28:54 +08:00
|
|
|
void LLVMContext::setDiscardValueNames(bool Discard) {
|
|
|
|
pImpl->DiscardValueNames = Discard;
|
|
|
|
}
|
2016-04-23 06:06:11 +08:00
|
|
|
|
2018-04-05 18:29:37 +08:00
|
|
|
OptPassGate &LLVMContext::getOptPassGate() const {
|
2018-03-28 00:57:20 +08:00
|
|
|
return pImpl->getOptPassGate();
|
2016-04-23 06:06:11 +08:00
|
|
|
}
|
2017-09-16 04:10:09 +08:00
|
|
|
|
2018-04-05 18:29:37 +08:00
|
|
|
void LLVMContext::setOptPassGate(OptPassGate& OPG) {
|
|
|
|
pImpl->setOptPassGate(OPG);
|
|
|
|
}
|
|
|
|
|
2017-09-16 04:10:09 +08:00
|
|
|
const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
|
|
|
|
return pImpl->DiagHandler.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
|
|
|
|
return std::move(pImpl->DiagHandler);
|
|
|
|
}
|