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"
|
2019-10-29 05:53:31 +08:00
|
|
|
#include "llvm/IR/LLVMRemarkStreamer.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-10-29 05:53:31 +08:00
|
|
|
#include "llvm/Remarks/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[] = {
|
2019-07-30 04:24:20 +08:00
|
|
|
#define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name},
|
|
|
|
#include "llvm/IR/FixedMetadataKinds.def"
|
|
|
|
#undef LLVM_FIXED_MD_KIND
|
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
|
|
|
|
Add Windows Control Flow Guard checks (/guard:cf).
Summary:
A new function pass (Transforms/CFGuard/CFGuard.cpp) inserts CFGuard checks on
indirect function calls, using either the check mechanism (X86, ARM, AArch64) or
or the dispatch mechanism (X86-64). The check mechanism requires a new calling
convention for the supported targets. The dispatch mechanism adds the target as
an operand bundle, which is processed by SelectionDAG. Another pass
(CodeGen/CFGuardLongjmp.cpp) identifies and emits valid longjmp targets, as
required by /guard:cf. This feature is enabled using the `cfguard` CC1 option.
Reviewers: thakis, rnk, theraven, pcc
Subscribers: ychen, hans, metalcanine, dmajor, tomrittervg, alex, mehdi_amini, mgorny, javed.absar, kristof.beyls, hiraditya, steven_wu, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D65761
2019-10-28 21:22:19 +08:00
|
|
|
auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget");
|
|
|
|
assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget &&
|
|
|
|
"cfguardtarget operand bundle id drifted!");
|
|
|
|
(void)CFGuardTargetEntry;
|
|
|
|
|
2020-02-15 06:16:53 +08:00
|
|
|
auto *PreallocatedEntry = pImpl->getOrInsertBundleTag("preallocated");
|
|
|
|
assert(PreallocatedEntry->second == LLVMContext::OB_preallocated &&
|
|
|
|
"preallocated operand bundle id drifted!");
|
|
|
|
(void)PreallocatedEntry;
|
|
|
|
|
2020-06-04 05:56:24 +08:00
|
|
|
auto *GCLiveEntry = pImpl->getOrInsertBundleTag("gc-live");
|
|
|
|
assert(GCLiveEntry->second == LLVMContext::OB_gc_live &&
|
|
|
|
"gc-transition operand bundle id drifted!");
|
|
|
|
(void)GCLiveEntry;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-11-18 02:37:59 +08:00
|
|
|
void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) {
|
2017-07-01 07:14:53 +08:00
|
|
|
pImpl->DiagnosticsHotnessThreshold = Threshold;
|
|
|
|
}
|
2020-11-18 02:43:02 +08:00
|
|
|
|
2017-07-01 07:14:53 +08:00
|
|
|
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
|
2020-11-18 02:37:59 +08:00
|
|
|
return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX);
|
2017-07-01 07:14:53 +08:00
|
|
|
}
|
|
|
|
|
2020-11-18 02:43:02 +08:00
|
|
|
bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {
|
|
|
|
return !pImpl->DiagnosticsHotnessThreshold.hasValue();
|
|
|
|
}
|
|
|
|
|
2019-10-29 05:53:31 +08:00
|
|
|
remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {
|
|
|
|
return pImpl->MainRemarkStreamer.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-10-29 05:53:31 +08:00
|
|
|
const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const {
|
|
|
|
return const_cast<LLVMContext *>(this)->getMainRemarkStreamer();
|
2019-03-06 23:20:13 +08:00
|
|
|
}
|
2019-10-29 05:53:31 +08:00
|
|
|
void LLVMContext::setMainRemarkStreamer(
|
|
|
|
std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {
|
|
|
|
pImpl->MainRemarkStreamer = std::move(RemarkStreamer);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() {
|
2020-02-05 09:42:47 +08:00
|
|
|
return pImpl->LLVMRS.get();
|
2019-10-29 05:53:31 +08:00
|
|
|
}
|
|
|
|
const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const {
|
|
|
|
return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();
|
|
|
|
}
|
|
|
|
void LLVMContext::setLLVMRemarkStreamer(
|
|
|
|
std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {
|
2020-02-05 09:42:47 +08:00
|
|
|
pImpl->LLVMRS = 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))
|
2019-10-29 05:53:31 +08:00
|
|
|
if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer())
|
2019-03-06 23:20:13 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2020-05-07 19:41:20 +08:00
|
|
|
StringMapEntry<uint32_t> *
|
|
|
|
LLVMContext::getOrInsertBundleTag(StringRef TagName) const {
|
|
|
|
return pImpl->getOrInsertBundleTag(TagName);
|
|
|
|
}
|
|
|
|
|
2015-09-25 03:14:18 +08:00
|
|
|
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);
|
|
|
|
}
|