mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 17:02:03 +00:00
4b43384841
Changes: * Change `ToVectorTy` to deal directly with `ElementCount` instances. * `VF == 1` replaced with `VF.isScalar()`. * `VF > 1` and `VF >=2` replaced with `VF.isVector()`. * `VF <=1` is replaced with `VF.isZero() || VF.isScalar()`. * Replaced the uses of `llvm::SmallSet<ElementCount, ...>` with `llvm::SmallSetVector<ElementCount, ...>`. This avoids the need of an ordering function for the `ElementCount` class. * Bits and pieces around printing the `ElementCount` to string streams. To guarantee that this change is a NFC, `VF.Min` and asserts are used in the following places: 1. When it doesn't make sense to deal with the scalable property, for example: a. When computing unrolling factors. b. When shuffle masks are built for fixed width vector types In this cases, an assert(!VF.Scalable && "<mgs>") has been added to make sure we don't enter coepaths that don't make sense for scalable vectors. 2. When there is a conscious decision to use `FixedVectorType`. These uses of `FixedVectorType` will likely be removed in favour of `VectorType` once the vectorizer is generic enough to deal with both fixed vector types and scalable vector types. 3. When dealing with building constants out of the value of VF, for example when computing the vectorization `step`, or building vectors of indices. These operation _make sense_ for scalable vectors too, but changing the code in these places to be generic and make it work for scalable vectors is to be submitted in a separate patch, as it is a functional change. 4. When building the potential VFs in VPlan. Making the VPlan generic enough to handle scalable vectorization factors is a functional change that needs a separate patch. See for example `void LoopVectorizationPlanner::buildVPlans(unsigned MinVF, unsigned MaxVF)`. 5. The class `IntrinsicCostAttribute`: this class still uses `unsigned VF` as updating the field to use `ElementCount` woudl require changes that could result in changing the behavior of the compiler. Will be done in a separate patch. 7. When dealing with user input for forcing the vectorization factor. In this case, adding support for scalable vectorization is a functional change that migh require changes at command line. Note that in some places the idiom ``` unsigned VF = ... auto VTy = FixedVectorType::get(ScalarTy, VF) ``` has been replaced with ``` ElementCount VF = ... assert(!VF.Scalable && ...); auto VTy = VectorType::get(ScalarTy, VF) ``` The assertion guarantees that the new code is (at least in debug mode) functionally equivalent to the old version. Notice that this change had been possible because none of the methods that are specific to `FixedVectorType` were used after the instantiation of `VTy`. Reviewed By: rengolin, ctetreau Differential Revision: https://reviews.llvm.org/D85794
391 lines
14 KiB
C++
391 lines
14 KiB
C++
//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the different classes involved in low level diagnostics.
|
|
//
|
|
// Diagnostics reporting is still done as part of the LLVMContext.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/IR/DiagnosticInfo.h"
|
|
#include "LLVMContextImpl.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/ADT/Twine.h"
|
|
#include "llvm/ADT/iterator_range.h"
|
|
#include "llvm/IR/BasicBlock.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/DebugInfoMetadata.h"
|
|
#include "llvm/IR/DerivedTypes.h"
|
|
#include "llvm/IR/DiagnosticPrinter.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/GlobalValue.h"
|
|
#include "llvm/IR/Instruction.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/IR/Metadata.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/IR/Type.h"
|
|
#include "llvm/IR/Value.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/Path.h"
|
|
#include "llvm/Support/Regex.h"
|
|
#include "llvm/Support/ScopedPrinter.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <atomic>
|
|
#include <cassert>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
using namespace llvm;
|
|
|
|
int llvm::getNextAvailablePluginDiagnosticKind() {
|
|
static std::atomic<int> PluginKindID(DK_FirstPluginKind);
|
|
return ++PluginKindID;
|
|
}
|
|
|
|
const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
|
|
|
|
DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
|
|
const Twine &MsgStr,
|
|
DiagnosticSeverity Severity)
|
|
: DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
|
|
if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
|
|
if (SrcLoc->getNumOperands() != 0)
|
|
if (const auto *CI =
|
|
mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
|
|
LocCookie = CI->getZExtValue();
|
|
}
|
|
}
|
|
|
|
void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
|
|
DP << getMsgStr();
|
|
if (getLocCookie())
|
|
DP << " at line " << getLocCookie();
|
|
}
|
|
|
|
void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
|
|
DP << getResourceName() << " limit";
|
|
|
|
if (getResourceLimit() != 0)
|
|
DP << " of " << getResourceLimit();
|
|
|
|
DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
|
|
}
|
|
|
|
void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
|
|
DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
|
|
<< ") in " << getModule();
|
|
}
|
|
|
|
void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
|
|
DiagnosticPrinter &DP) const {
|
|
DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
|
|
}
|
|
|
|
void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
|
|
if (!FileName.empty()) {
|
|
DP << getFileName();
|
|
if (LineNum > 0)
|
|
DP << ":" << getLineNum();
|
|
DP << ": ";
|
|
}
|
|
DP << getMsg();
|
|
}
|
|
|
|
void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
|
|
if (getFileName())
|
|
DP << getFileName() << ": ";
|
|
DP << getMsg();
|
|
}
|
|
|
|
void DiagnosticInfo::anchor() {}
|
|
void DiagnosticInfoStackSize::anchor() {}
|
|
void DiagnosticInfoWithLocationBase::anchor() {}
|
|
void DiagnosticInfoIROptimization::anchor() {}
|
|
|
|
DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
|
|
if (!DL)
|
|
return;
|
|
File = DL->getFile();
|
|
Line = DL->getLine();
|
|
Column = DL->getColumn();
|
|
}
|
|
|
|
DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
|
|
if (!SP)
|
|
return;
|
|
|
|
File = SP->getFile();
|
|
Line = SP->getScopeLine();
|
|
Column = 0;
|
|
}
|
|
|
|
StringRef DiagnosticLocation::getRelativePath() const {
|
|
return File->getFilename();
|
|
}
|
|
|
|
std::string DiagnosticLocation::getAbsolutePath() const {
|
|
StringRef Name = File->getFilename();
|
|
if (sys::path::is_absolute(Name))
|
|
return std::string(Name);
|
|
|
|
SmallString<128> Path;
|
|
sys::path::append(Path, File->getDirectory(), Name);
|
|
return sys::path::remove_leading_dotslash(Path).str();
|
|
}
|
|
|
|
std::string DiagnosticInfoWithLocationBase::getAbsolutePath() const {
|
|
return Loc.getAbsolutePath();
|
|
}
|
|
|
|
void DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath,
|
|
unsigned &Line,
|
|
unsigned &Column) const {
|
|
RelativePath = Loc.getRelativePath();
|
|
Line = Loc.getLine();
|
|
Column = Loc.getColumn();
|
|
}
|
|
|
|
const std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
|
|
StringRef Filename("<unknown>");
|
|
unsigned Line = 0;
|
|
unsigned Column = 0;
|
|
if (isLocationAvailable())
|
|
getLocation(Filename, Line, Column);
|
|
return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
|
|
}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
|
|
const Value *V)
|
|
: Key(std::string(Key)) {
|
|
if (auto *F = dyn_cast<Function>(V)) {
|
|
if (DISubprogram *SP = F->getSubprogram())
|
|
Loc = SP;
|
|
}
|
|
else if (auto *I = dyn_cast<Instruction>(V))
|
|
Loc = I->getDebugLoc();
|
|
|
|
// Only include names that correspond to user variables. FIXME: We should use
|
|
// debug info if available to get the name of the user variable.
|
|
if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
|
|
Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));
|
|
else if (isa<Constant>(V)) {
|
|
raw_string_ostream OS(Val);
|
|
V->printAsOperand(OS, /*PrintType=*/false);
|
|
} else if (auto *I = dyn_cast<Instruction>(V))
|
|
Val = I->getOpcodeName();
|
|
}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
|
|
: Key(std::string(Key)) {
|
|
raw_string_ostream OS(Val);
|
|
OS << *T;
|
|
}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
|
|
: Key(std::string(Key)), Val(S.str()) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
|
|
: Key(std::string(Key)), Val(itostr(N)) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)
|
|
: Key(std::string(Key)), Val(llvm::to_string(N)) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
|
|
: Key(std::string(Key)), Val(itostr(N)) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)
|
|
: Key(std::string(Key)), Val(itostr(N)) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
|
|
: Key(std::string(Key)), Val(utostr(N)) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
|
|
unsigned long N)
|
|
: Key(std::string(Key)), Val(utostr(N)) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
|
|
unsigned long long N)
|
|
: Key(std::string(Key)), Val(utostr(N)) {}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
|
|
ElementCount EC)
|
|
: Key(std::string(Key)) {
|
|
raw_string_ostream OS(Val);
|
|
EC.print(OS);
|
|
}
|
|
|
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
|
|
: Key(std::string(Key)), Loc(Loc) {
|
|
if (Loc) {
|
|
Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
|
|
Twine(Loc.getCol())).str();
|
|
} else {
|
|
Val = "<UNKNOWN LOCATION>";
|
|
}
|
|
}
|
|
|
|
void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
|
|
DP << getLocationStr() << ": " << getMsg();
|
|
if (Hotness)
|
|
DP << " (hotness: " << *Hotness << ")";
|
|
}
|
|
|
|
OptimizationRemark::OptimizationRemark(const char *PassName,
|
|
StringRef RemarkName,
|
|
const DiagnosticLocation &Loc,
|
|
const Value *CodeRegion)
|
|
: DiagnosticInfoIROptimization(
|
|
DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
|
|
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
|
|
|
|
OptimizationRemark::OptimizationRemark(const char *PassName,
|
|
StringRef RemarkName,
|
|
const Instruction *Inst)
|
|
: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
|
|
RemarkName, *Inst->getParent()->getParent(),
|
|
Inst->getDebugLoc(), Inst->getParent()) {}
|
|
|
|
static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
|
|
return Func->empty() ? nullptr : &Func->front();
|
|
}
|
|
|
|
OptimizationRemark::OptimizationRemark(const char *PassName,
|
|
StringRef RemarkName,
|
|
const Function *Func)
|
|
: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
|
|
RemarkName, *Func, Func->getSubprogram(),
|
|
getFirstFunctionBlock(Func)) {}
|
|
|
|
bool OptimizationRemark::isEnabled() const {
|
|
const Function &Fn = getFunction();
|
|
LLVMContext &Ctx = Fn.getContext();
|
|
return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
|
|
}
|
|
|
|
OptimizationRemarkMissed::OptimizationRemarkMissed(
|
|
const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
|
|
const Value *CodeRegion)
|
|
: DiagnosticInfoIROptimization(
|
|
DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
|
|
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
|
|
|
|
OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
|
|
StringRef RemarkName,
|
|
const Instruction *Inst)
|
|
: DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
|
|
PassName, RemarkName,
|
|
*Inst->getParent()->getParent(),
|
|
Inst->getDebugLoc(), Inst->getParent()) {}
|
|
|
|
bool OptimizationRemarkMissed::isEnabled() const {
|
|
const Function &Fn = getFunction();
|
|
LLVMContext &Ctx = Fn.getContext();
|
|
return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
|
|
}
|
|
|
|
OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
|
|
const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
|
|
const Value *CodeRegion)
|
|
: DiagnosticInfoIROptimization(
|
|
DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
|
|
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
|
|
|
|
OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
|
|
StringRef RemarkName,
|
|
const Instruction *Inst)
|
|
: DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
|
|
PassName, RemarkName,
|
|
*Inst->getParent()->getParent(),
|
|
Inst->getDebugLoc(), Inst->getParent()) {}
|
|
|
|
OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
|
|
enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
|
|
const DiagnosticLocation &Loc, const Value *CodeRegion)
|
|
: DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
|
|
*cast<BasicBlock>(CodeRegion)->getParent(),
|
|
Loc, CodeRegion) {}
|
|
|
|
bool OptimizationRemarkAnalysis::isEnabled() const {
|
|
const Function &Fn = getFunction();
|
|
LLVMContext &Ctx = Fn.getContext();
|
|
return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
|
|
shouldAlwaysPrint();
|
|
}
|
|
|
|
void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
|
|
DP << Diagnostic;
|
|
}
|
|
|
|
DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
|
|
const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
|
|
const Value *CodeRegion)
|
|
: DiagnosticInfoIROptimization(
|
|
DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
|
|
*cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
|
|
|
|
bool DiagnosticInfoOptimizationFailure::isEnabled() const {
|
|
// Only print warnings.
|
|
return getSeverity() == DS_Warning;
|
|
}
|
|
|
|
void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
|
|
std::string Str;
|
|
raw_string_ostream OS(Str);
|
|
|
|
OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
|
|
<< *getFunction().getFunctionType() << ": " << Msg << '\n';
|
|
OS.flush();
|
|
DP << Str;
|
|
}
|
|
|
|
void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
|
|
DP << "Instruction selection used fallback path for " << getFunction();
|
|
}
|
|
|
|
void DiagnosticInfoOptimizationBase::insert(StringRef S) {
|
|
Args.emplace_back(S);
|
|
}
|
|
|
|
void DiagnosticInfoOptimizationBase::insert(Argument A) {
|
|
Args.push_back(std::move(A));
|
|
}
|
|
|
|
void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {
|
|
IsVerbose = true;
|
|
}
|
|
|
|
void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {
|
|
FirstExtraArgIndex = Args.size();
|
|
}
|
|
|
|
std::string DiagnosticInfoOptimizationBase::getMsg() const {
|
|
std::string Str;
|
|
raw_string_ostream OS(Str);
|
|
for (const DiagnosticInfoOptimizationBase::Argument &Arg :
|
|
make_range(Args.begin(), FirstExtraArgIndex == -1
|
|
? Args.end()
|
|
: Args.begin() + FirstExtraArgIndex))
|
|
OS << Arg.Val;
|
|
return OS.str();
|
|
}
|
|
|
|
DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,
|
|
Twine &Msg)
|
|
: DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,
|
|
*Inst->getParent()->getParent(),
|
|
Inst->getDebugLoc()),
|
|
Msg(Msg) {}
|
|
|
|
void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {
|
|
DP << getLocationStr() << ": " << getMsg();
|
|
}
|
|
|
|
void OptimizationRemarkAnalysisFPCommute::anchor() {}
|
|
void OptimizationRemarkAnalysisAliasing::anchor() {}
|