You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
@ -1 +0,0 @@
|
||||
0fafe82404e4db8f2036a55bcafb157a27a2cada
|
261
external/llvm/lib/IR/AttributeImpl.h
vendored
261
external/llvm/lib/IR/AttributeImpl.h
vendored
@ -1,261 +0,0 @@
|
||||
//===- AttributeImpl.h - Attribute Internals --------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file defines various helper methods and classes used by
|
||||
/// LLVMContextImpl for creating and managing attributes.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H
|
||||
#define LLVM_LIB_IR_ATTRIBUTEIMPL_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LLVMContext;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \class
|
||||
/// \brief This class represents a single, uniqued attribute. That attribute
|
||||
/// could be a single enum, a tuple, or a string.
|
||||
class AttributeImpl : public FoldingSetNode {
|
||||
unsigned char KindID; ///< Holds the AttrEntryKind of the attribute
|
||||
|
||||
protected:
|
||||
enum AttrEntryKind {
|
||||
EnumAttrEntry,
|
||||
IntAttrEntry,
|
||||
StringAttrEntry
|
||||
};
|
||||
|
||||
AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {}
|
||||
|
||||
public:
|
||||
// AttributesImpl is uniqued, these should not be available.
|
||||
AttributeImpl(const AttributeImpl &) = delete;
|
||||
AttributeImpl &operator=(const AttributeImpl &) = delete;
|
||||
|
||||
virtual ~AttributeImpl();
|
||||
|
||||
bool isEnumAttribute() const { return KindID == EnumAttrEntry; }
|
||||
bool isIntAttribute() const { return KindID == IntAttrEntry; }
|
||||
bool isStringAttribute() const { return KindID == StringAttrEntry; }
|
||||
|
||||
bool hasAttribute(Attribute::AttrKind A) const;
|
||||
bool hasAttribute(StringRef Kind) const;
|
||||
|
||||
Attribute::AttrKind getKindAsEnum() const;
|
||||
uint64_t getValueAsInt() const;
|
||||
|
||||
StringRef getKindAsString() const;
|
||||
StringRef getValueAsString() const;
|
||||
|
||||
/// \brief Used when sorting the attributes.
|
||||
bool operator<(const AttributeImpl &AI) const;
|
||||
|
||||
void Profile(FoldingSetNodeID &ID) const {
|
||||
if (isEnumAttribute())
|
||||
Profile(ID, getKindAsEnum(), 0);
|
||||
else if (isIntAttribute())
|
||||
Profile(ID, getKindAsEnum(), getValueAsInt());
|
||||
else
|
||||
Profile(ID, getKindAsString(), getValueAsString());
|
||||
}
|
||||
|
||||
static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
|
||||
uint64_t Val) {
|
||||
ID.AddInteger(Kind);
|
||||
if (Val) ID.AddInteger(Val);
|
||||
}
|
||||
|
||||
static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) {
|
||||
ID.AddString(Kind);
|
||||
if (!Values.empty()) ID.AddString(Values);
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \class
|
||||
/// \brief A set of classes that contain the value of the
|
||||
/// attribute object. There are three main categories: enum attribute entries,
|
||||
/// represented by Attribute::AttrKind; alignment attribute entries; and string
|
||||
/// attribute enties, which are for target-dependent attributes.
|
||||
|
||||
class EnumAttributeImpl : public AttributeImpl {
|
||||
virtual void anchor();
|
||||
|
||||
Attribute::AttrKind Kind;
|
||||
|
||||
protected:
|
||||
EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind)
|
||||
: AttributeImpl(ID), Kind(Kind) {}
|
||||
|
||||
public:
|
||||
EnumAttributeImpl(Attribute::AttrKind Kind)
|
||||
: AttributeImpl(EnumAttrEntry), Kind(Kind) {}
|
||||
|
||||
Attribute::AttrKind getEnumKind() const { return Kind; }
|
||||
};
|
||||
|
||||
class IntAttributeImpl : public EnumAttributeImpl {
|
||||
uint64_t Val;
|
||||
|
||||
void anchor() override;
|
||||
|
||||
public:
|
||||
IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val)
|
||||
: EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {
|
||||
assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment ||
|
||||
Kind == Attribute::Dereferenceable ||
|
||||
Kind == Attribute::DereferenceableOrNull ||
|
||||
Kind == Attribute::AllocSize) &&
|
||||
"Wrong kind for int attribute!");
|
||||
}
|
||||
|
||||
uint64_t getValue() const { return Val; }
|
||||
};
|
||||
|
||||
class StringAttributeImpl : public AttributeImpl {
|
||||
virtual void anchor();
|
||||
|
||||
std::string Kind;
|
||||
std::string Val;
|
||||
|
||||
public:
|
||||
StringAttributeImpl(StringRef Kind, StringRef Val = StringRef())
|
||||
: AttributeImpl(StringAttrEntry), Kind(Kind), Val(Val) {}
|
||||
|
||||
StringRef getStringKind() const { return Kind; }
|
||||
StringRef getStringValue() const { return Val; }
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \class
|
||||
/// \brief This class represents a group of attributes that apply to one
|
||||
/// element: function, return type, or parameter.
|
||||
class AttributeSetNode final
|
||||
: public FoldingSetNode,
|
||||
private TrailingObjects<AttributeSetNode, Attribute> {
|
||||
friend TrailingObjects;
|
||||
|
||||
/// Bitset with a bit for each available attribute Attribute::AttrKind.
|
||||
uint64_t AvailableAttrs;
|
||||
unsigned NumAttrs; ///< Number of attributes in this node.
|
||||
|
||||
AttributeSetNode(ArrayRef<Attribute> Attrs);
|
||||
|
||||
public:
|
||||
// AttributesSetNode is uniqued, these should not be available.
|
||||
AttributeSetNode(const AttributeSetNode &) = delete;
|
||||
AttributeSetNode &operator=(const AttributeSetNode &) = delete;
|
||||
|
||||
void operator delete(void *p) { ::operator delete(p); }
|
||||
|
||||
static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);
|
||||
|
||||
static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
|
||||
|
||||
/// \brief Return the number of attributes this AttributeList contains.
|
||||
unsigned getNumAttributes() const { return NumAttrs; }
|
||||
|
||||
bool hasAttribute(Attribute::AttrKind Kind) const {
|
||||
return AvailableAttrs & ((uint64_t)1) << Kind;
|
||||
}
|
||||
bool hasAttribute(StringRef Kind) const;
|
||||
bool hasAttributes() const { return NumAttrs != 0; }
|
||||
|
||||
Attribute getAttribute(Attribute::AttrKind Kind) const;
|
||||
Attribute getAttribute(StringRef Kind) const;
|
||||
|
||||
unsigned getAlignment() const;
|
||||
unsigned getStackAlignment() const;
|
||||
uint64_t getDereferenceableBytes() const;
|
||||
uint64_t getDereferenceableOrNullBytes() const;
|
||||
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
|
||||
std::string getAsString(bool InAttrGrp) const;
|
||||
|
||||
using iterator = const Attribute *;
|
||||
|
||||
iterator begin() const { return getTrailingObjects<Attribute>(); }
|
||||
iterator end() const { return begin() + NumAttrs; }
|
||||
|
||||
void Profile(FoldingSetNodeID &ID) const {
|
||||
Profile(ID, makeArrayRef(begin(), end()));
|
||||
}
|
||||
|
||||
static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
|
||||
for (const auto &Attr : AttrList)
|
||||
Attr.Profile(ID);
|
||||
}
|
||||
};
|
||||
|
||||
using IndexAttrPair = std::pair<unsigned, AttributeSet>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \class
|
||||
/// \brief This class represents a set of attributes that apply to the function,
|
||||
/// return type, and parameters.
|
||||
class AttributeListImpl final
|
||||
: public FoldingSetNode,
|
||||
private TrailingObjects<AttributeListImpl, AttributeSet> {
|
||||
friend class AttributeList;
|
||||
friend TrailingObjects;
|
||||
|
||||
private:
|
||||
/// Bitset with a bit for each available attribute Attribute::AttrKind.
|
||||
uint64_t AvailableFunctionAttrs;
|
||||
LLVMContext &Context;
|
||||
unsigned NumAttrSets; ///< Number of entries in this set.
|
||||
|
||||
// Helper fn for TrailingObjects class.
|
||||
size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; }
|
||||
|
||||
public:
|
||||
AttributeListImpl(LLVMContext &C, ArrayRef<AttributeSet> Sets);
|
||||
|
||||
// AttributesSetImpt is uniqued, these should not be available.
|
||||
AttributeListImpl(const AttributeListImpl &) = delete;
|
||||
AttributeListImpl &operator=(const AttributeListImpl &) = delete;
|
||||
|
||||
void operator delete(void *p) { ::operator delete(p); }
|
||||
|
||||
/// \brief Get the context that created this AttributeListImpl.
|
||||
LLVMContext &getContext() { return Context; }
|
||||
|
||||
/// \brief Return true if the AttributeSet or the FunctionIndex has an
|
||||
/// enum attribute of the given kind.
|
||||
bool hasFnAttribute(Attribute::AttrKind Kind) const {
|
||||
return AvailableFunctionAttrs & ((uint64_t)1) << Kind;
|
||||
}
|
||||
|
||||
using iterator = const AttributeSet *;
|
||||
|
||||
iterator begin() const { return getTrailingObjects<AttributeSet>(); }
|
||||
iterator end() const { return begin() + NumAttrSets; }
|
||||
|
||||
void Profile(FoldingSetNodeID &ID) const;
|
||||
static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeSet> Nodes);
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H
|
1687
external/llvm/lib/IR/Attributes.cpp
vendored
1687
external/llvm/lib/IR/Attributes.cpp
vendored
File diff suppressed because it is too large
Load Diff
1
external/llvm/lib/IR/AttributesCompatFunc.td
vendored
1
external/llvm/lib/IR/AttributesCompatFunc.td
vendored
@ -1 +0,0 @@
|
||||
include "llvm/IR/Attributes.td"
|
@ -1 +0,0 @@
|
||||
c56a022c6705e846e493c2bc56c0ea12b7bf3035
|
463
external/llvm/lib/IR/BasicBlock.cpp
vendored
463
external/llvm/lib/IR/BasicBlock.cpp
vendored
@ -1,463 +0,0 @@
|
||||
//===-- BasicBlock.cpp - Implement BasicBlock related methods -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the BasicBlock class for the IR library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "SymbolTableListTraitsImpl.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
ValueSymbolTable *BasicBlock::getValueSymbolTable() {
|
||||
if (Function *F = getParent())
|
||||
return F->getValueSymbolTable();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LLVMContext &BasicBlock::getContext() const {
|
||||
return getType()->getContext();
|
||||
}
|
||||
|
||||
// Explicit instantiation of SymbolTableListTraits since some of the methods
|
||||
// are not in the public header file...
|
||||
template class llvm::SymbolTableListTraits<Instruction>;
|
||||
|
||||
BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
|
||||
BasicBlock *InsertBefore)
|
||||
: Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr) {
|
||||
|
||||
if (NewParent)
|
||||
insertInto(NewParent, InsertBefore);
|
||||
else
|
||||
assert(!InsertBefore &&
|
||||
"Cannot insert block before another block with no function!");
|
||||
|
||||
setName(Name);
|
||||
}
|
||||
|
||||
void BasicBlock::insertInto(Function *NewParent, BasicBlock *InsertBefore) {
|
||||
assert(NewParent && "Expected a parent");
|
||||
assert(!Parent && "Already has a parent");
|
||||
|
||||
if (InsertBefore)
|
||||
NewParent->getBasicBlockList().insert(InsertBefore->getIterator(), this);
|
||||
else
|
||||
NewParent->getBasicBlockList().push_back(this);
|
||||
}
|
||||
|
||||
BasicBlock::~BasicBlock() {
|
||||
// If the address of the block is taken and it is being deleted (e.g. because
|
||||
// it is dead), this means that there is either a dangling constant expr
|
||||
// hanging off the block, or an undefined use of the block (source code
|
||||
// expecting the address of a label to keep the block alive even though there
|
||||
// is no indirect branch). Handle these cases by zapping the BlockAddress
|
||||
// nodes. There are no other possible uses at this point.
|
||||
if (hasAddressTaken()) {
|
||||
assert(!use_empty() && "There should be at least one blockaddress!");
|
||||
Constant *Replacement =
|
||||
ConstantInt::get(llvm::Type::getInt32Ty(getContext()), 1);
|
||||
while (!use_empty()) {
|
||||
BlockAddress *BA = cast<BlockAddress>(user_back());
|
||||
BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement,
|
||||
BA->getType()));
|
||||
BA->destroyConstant();
|
||||
}
|
||||
}
|
||||
|
||||
assert(getParent() == nullptr && "BasicBlock still linked into the program!");
|
||||
dropAllReferences();
|
||||
InstList.clear();
|
||||
}
|
||||
|
||||
void BasicBlock::setParent(Function *parent) {
|
||||
// Set Parent=parent, updating instruction symtab entries as appropriate.
|
||||
InstList.setSymTabObject(&Parent, parent);
|
||||
}
|
||||
|
||||
void BasicBlock::removeFromParent() {
|
||||
getParent()->getBasicBlockList().remove(getIterator());
|
||||
}
|
||||
|
||||
iplist<BasicBlock>::iterator BasicBlock::eraseFromParent() {
|
||||
return getParent()->getBasicBlockList().erase(getIterator());
|
||||
}
|
||||
|
||||
/// Unlink this basic block from its current function and
|
||||
/// insert it into the function that MovePos lives in, right before MovePos.
|
||||
void BasicBlock::moveBefore(BasicBlock *MovePos) {
|
||||
MovePos->getParent()->getBasicBlockList().splice(
|
||||
MovePos->getIterator(), getParent()->getBasicBlockList(), getIterator());
|
||||
}
|
||||
|
||||
/// Unlink this basic block from its current function and
|
||||
/// insert it into the function that MovePos lives in, right after MovePos.
|
||||
void BasicBlock::moveAfter(BasicBlock *MovePos) {
|
||||
MovePos->getParent()->getBasicBlockList().splice(
|
||||
++MovePos->getIterator(), getParent()->getBasicBlockList(),
|
||||
getIterator());
|
||||
}
|
||||
|
||||
const Module *BasicBlock::getModule() const {
|
||||
return getParent()->getParent();
|
||||
}
|
||||
|
||||
const TerminatorInst *BasicBlock::getTerminator() const {
|
||||
if (InstList.empty()) return nullptr;
|
||||
return dyn_cast<TerminatorInst>(&InstList.back());
|
||||
}
|
||||
|
||||
const CallInst *BasicBlock::getTerminatingMustTailCall() const {
|
||||
if (InstList.empty())
|
||||
return nullptr;
|
||||
const ReturnInst *RI = dyn_cast<ReturnInst>(&InstList.back());
|
||||
if (!RI || RI == &InstList.front())
|
||||
return nullptr;
|
||||
|
||||
const Instruction *Prev = RI->getPrevNode();
|
||||
if (!Prev)
|
||||
return nullptr;
|
||||
|
||||
if (Value *RV = RI->getReturnValue()) {
|
||||
if (RV != Prev)
|
||||
return nullptr;
|
||||
|
||||
// Look through the optional bitcast.
|
||||
if (auto *BI = dyn_cast<BitCastInst>(Prev)) {
|
||||
RV = BI->getOperand(0);
|
||||
Prev = BI->getPrevNode();
|
||||
if (!Prev || RV != Prev)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto *CI = dyn_cast<CallInst>(Prev)) {
|
||||
if (CI->isMustTailCall())
|
||||
return CI;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CallInst *BasicBlock::getTerminatingDeoptimizeCall() const {
|
||||
if (InstList.empty())
|
||||
return nullptr;
|
||||
auto *RI = dyn_cast<ReturnInst>(&InstList.back());
|
||||
if (!RI || RI == &InstList.front())
|
||||
return nullptr;
|
||||
|
||||
if (auto *CI = dyn_cast_or_null<CallInst>(RI->getPrevNode()))
|
||||
if (Function *F = CI->getCalledFunction())
|
||||
if (F->getIntrinsicID() == Intrinsic::experimental_deoptimize)
|
||||
return CI;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Instruction* BasicBlock::getFirstNonPHI() const {
|
||||
for (const Instruction &I : *this)
|
||||
if (!isa<PHINode>(I))
|
||||
return &I;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Instruction* BasicBlock::getFirstNonPHIOrDbg() const {
|
||||
for (const Instruction &I : *this)
|
||||
if (!isa<PHINode>(I) && !isa<DbgInfoIntrinsic>(I))
|
||||
return &I;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Instruction* BasicBlock::getFirstNonPHIOrDbgOrLifetime() const {
|
||||
for (const Instruction &I : *this) {
|
||||
if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
|
||||
continue;
|
||||
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(&I))
|
||||
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
|
||||
II->getIntrinsicID() == Intrinsic::lifetime_end)
|
||||
continue;
|
||||
|
||||
return &I;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BasicBlock::const_iterator BasicBlock::getFirstInsertionPt() const {
|
||||
const Instruction *FirstNonPHI = getFirstNonPHI();
|
||||
if (!FirstNonPHI)
|
||||
return end();
|
||||
|
||||
const_iterator InsertPt = FirstNonPHI->getIterator();
|
||||
if (InsertPt->isEHPad()) ++InsertPt;
|
||||
return InsertPt;
|
||||
}
|
||||
|
||||
void BasicBlock::dropAllReferences() {
|
||||
for (Instruction &I : *this)
|
||||
I.dropAllReferences();
|
||||
}
|
||||
|
||||
/// If this basic block has a single predecessor block,
|
||||
/// return the block, otherwise return a null pointer.
|
||||
const BasicBlock *BasicBlock::getSinglePredecessor() const {
|
||||
const_pred_iterator PI = pred_begin(this), E = pred_end(this);
|
||||
if (PI == E) return nullptr; // No preds.
|
||||
const BasicBlock *ThePred = *PI;
|
||||
++PI;
|
||||
return (PI == E) ? ThePred : nullptr /*multiple preds*/;
|
||||
}
|
||||
|
||||
/// If this basic block has a unique predecessor block,
|
||||
/// return the block, otherwise return a null pointer.
|
||||
/// Note that unique predecessor doesn't mean single edge, there can be
|
||||
/// multiple edges from the unique predecessor to this block (for example
|
||||
/// a switch statement with multiple cases having the same destination).
|
||||
const BasicBlock *BasicBlock::getUniquePredecessor() const {
|
||||
const_pred_iterator PI = pred_begin(this), E = pred_end(this);
|
||||
if (PI == E) return nullptr; // No preds.
|
||||
const BasicBlock *PredBB = *PI;
|
||||
++PI;
|
||||
for (;PI != E; ++PI) {
|
||||
if (*PI != PredBB)
|
||||
return nullptr;
|
||||
// The same predecessor appears multiple times in the predecessor list.
|
||||
// This is OK.
|
||||
}
|
||||
return PredBB;
|
||||
}
|
||||
|
||||
const BasicBlock *BasicBlock::getSingleSuccessor() const {
|
||||
succ_const_iterator SI = succ_begin(this), E = succ_end(this);
|
||||
if (SI == E) return nullptr; // no successors
|
||||
const BasicBlock *TheSucc = *SI;
|
||||
++SI;
|
||||
return (SI == E) ? TheSucc : nullptr /* multiple successors */;
|
||||
}
|
||||
|
||||
const BasicBlock *BasicBlock::getUniqueSuccessor() const {
|
||||
succ_const_iterator SI = succ_begin(this), E = succ_end(this);
|
||||
if (SI == E) return nullptr; // No successors
|
||||
const BasicBlock *SuccBB = *SI;
|
||||
++SI;
|
||||
for (;SI != E; ++SI) {
|
||||
if (*SI != SuccBB)
|
||||
return nullptr;
|
||||
// The same successor appears multiple times in the successor list.
|
||||
// This is OK.
|
||||
}
|
||||
return SuccBB;
|
||||
}
|
||||
|
||||
iterator_range<BasicBlock::phi_iterator> BasicBlock::phis() {
|
||||
PHINode *P = empty() ? nullptr : dyn_cast<PHINode>(&*begin());
|
||||
return make_range<phi_iterator>(P, nullptr);
|
||||
}
|
||||
|
||||
/// This method is used to notify a BasicBlock that the
|
||||
/// specified Predecessor of the block is no longer able to reach it. This is
|
||||
/// actually not used to update the Predecessor list, but is actually used to
|
||||
/// update the PHI nodes that reside in the block. Note that this should be
|
||||
/// called while the predecessor still refers to this block.
|
||||
///
|
||||
void BasicBlock::removePredecessor(BasicBlock *Pred,
|
||||
bool DontDeleteUselessPHIs) {
|
||||
assert((hasNUsesOrMore(16)||// Reduce cost of this assertion for complex CFGs.
|
||||
find(pred_begin(this), pred_end(this), Pred) != pred_end(this)) &&
|
||||
"removePredecessor: BB is not a predecessor!");
|
||||
|
||||
if (InstList.empty()) return;
|
||||
PHINode *APN = dyn_cast<PHINode>(&front());
|
||||
if (!APN) return; // Quick exit.
|
||||
|
||||
// If there are exactly two predecessors, then we want to nuke the PHI nodes
|
||||
// altogether. However, we cannot do this, if this in this case:
|
||||
//
|
||||
// Loop:
|
||||
// %x = phi [X, Loop]
|
||||
// %x2 = add %x, 1 ;; This would become %x2 = add %x2, 1
|
||||
// br Loop ;; %x2 does not dominate all uses
|
||||
//
|
||||
// This is because the PHI node input is actually taken from the predecessor
|
||||
// basic block. The only case this can happen is with a self loop, so we
|
||||
// check for this case explicitly now.
|
||||
//
|
||||
unsigned max_idx = APN->getNumIncomingValues();
|
||||
assert(max_idx != 0 && "PHI Node in block with 0 predecessors!?!?!");
|
||||
if (max_idx == 2) {
|
||||
BasicBlock *Other = APN->getIncomingBlock(APN->getIncomingBlock(0) == Pred);
|
||||
|
||||
// Disable PHI elimination!
|
||||
if (this == Other) max_idx = 3;
|
||||
}
|
||||
|
||||
// <= Two predecessors BEFORE I remove one?
|
||||
if (max_idx <= 2 && !DontDeleteUselessPHIs) {
|
||||
// Yup, loop through and nuke the PHI nodes
|
||||
while (PHINode *PN = dyn_cast<PHINode>(&front())) {
|
||||
// Remove the predecessor first.
|
||||
PN->removeIncomingValue(Pred, !DontDeleteUselessPHIs);
|
||||
|
||||
// If the PHI _HAD_ two uses, replace PHI node with its now *single* value
|
||||
if (max_idx == 2) {
|
||||
if (PN->getIncomingValue(0) != PN)
|
||||
PN->replaceAllUsesWith(PN->getIncomingValue(0));
|
||||
else
|
||||
// We are left with an infinite loop with no entries: kill the PHI.
|
||||
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
|
||||
getInstList().pop_front(); // Remove the PHI node
|
||||
}
|
||||
|
||||
// If the PHI node already only had one entry, it got deleted by
|
||||
// removeIncomingValue.
|
||||
}
|
||||
} else {
|
||||
// Okay, now we know that we need to remove predecessor #pred_idx from all
|
||||
// PHI nodes. Iterate over each PHI node fixing them up
|
||||
PHINode *PN;
|
||||
for (iterator II = begin(); (PN = dyn_cast<PHINode>(II)); ) {
|
||||
++II;
|
||||
PN->removeIncomingValue(Pred, false);
|
||||
// If all incoming values to the Phi are the same, we can replace the Phi
|
||||
// with that value.
|
||||
Value* PNV = nullptr;
|
||||
if (!DontDeleteUselessPHIs && (PNV = PN->hasConstantValue()))
|
||||
if (PNV != PN) {
|
||||
PN->replaceAllUsesWith(PNV);
|
||||
PN->eraseFromParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicBlock::canSplitPredecessors() const {
|
||||
const Instruction *FirstNonPHI = getFirstNonPHI();
|
||||
if (isa<LandingPadInst>(FirstNonPHI))
|
||||
return true;
|
||||
// This is perhaps a little conservative because constructs like
|
||||
// CleanupBlockInst are pretty easy to split. However, SplitBlockPredecessors
|
||||
// cannot handle such things just yet.
|
||||
if (FirstNonPHI->isEHPad())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BasicBlock::isLegalToHoistInto() const {
|
||||
auto *Term = getTerminator();
|
||||
// No terminator means the block is under construction.
|
||||
if (!Term)
|
||||
return true;
|
||||
|
||||
// If the block has no successors, there can be no instructions to hoist.
|
||||
assert(Term->getNumSuccessors() > 0);
|
||||
|
||||
// Instructions should not be hoisted across exception handling boundaries.
|
||||
return !Term->isExceptional();
|
||||
}
|
||||
|
||||
/// This splits a basic block into two at the specified
|
||||
/// instruction. Note that all instructions BEFORE the specified iterator stay
|
||||
/// as part of the original basic block, an unconditional branch is added to
|
||||
/// the new BB, and the rest of the instructions in the BB are moved to the new
|
||||
/// BB, including the old terminator. This invalidates the iterator.
|
||||
///
|
||||
/// Note that this only works on well formed basic blocks (must have a
|
||||
/// terminator), and 'I' must not be the end of instruction list (which would
|
||||
/// cause a degenerate basic block to be formed, having a terminator inside of
|
||||
/// the basic block).
|
||||
///
|
||||
BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) {
|
||||
assert(getTerminator() && "Can't use splitBasicBlock on degenerate BB!");
|
||||
assert(I != InstList.end() &&
|
||||
"Trying to get me to create degenerate basic block!");
|
||||
|
||||
BasicBlock *New = BasicBlock::Create(getContext(), BBName, getParent(),
|
||||
this->getNextNode());
|
||||
|
||||
// Save DebugLoc of split point before invalidating iterator.
|
||||
DebugLoc Loc = I->getDebugLoc();
|
||||
// Move all of the specified instructions from the original basic block into
|
||||
// the new basic block.
|
||||
New->getInstList().splice(New->end(), this->getInstList(), I, end());
|
||||
|
||||
// Add a branch instruction to the newly formed basic block.
|
||||
BranchInst *BI = BranchInst::Create(New, this);
|
||||
BI->setDebugLoc(Loc);
|
||||
|
||||
// Now we must loop through all of the successors of the New block (which
|
||||
// _were_ the successors of the 'this' block), and update any PHI nodes in
|
||||
// successors. If there were PHI nodes in the successors, then they need to
|
||||
// know that incoming branches will be from New, not from Old.
|
||||
//
|
||||
for (succ_iterator I = succ_begin(New), E = succ_end(New); I != E; ++I) {
|
||||
// Loop over any phi nodes in the basic block, updating the BB field of
|
||||
// incoming values...
|
||||
BasicBlock *Successor = *I;
|
||||
for (auto &PN : Successor->phis()) {
|
||||
int Idx = PN.getBasicBlockIndex(this);
|
||||
while (Idx != -1) {
|
||||
PN.setIncomingBlock((unsigned)Idx, New);
|
||||
Idx = PN.getBasicBlockIndex(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return New;
|
||||
}
|
||||
|
||||
void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) {
|
||||
TerminatorInst *TI = getTerminator();
|
||||
if (!TI)
|
||||
// Cope with being called on a BasicBlock that doesn't have a terminator
|
||||
// yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this.
|
||||
return;
|
||||
for (BasicBlock *Succ : TI->successors()) {
|
||||
// N.B. Succ might not be a complete BasicBlock, so don't assume
|
||||
// that it ends with a non-phi instruction.
|
||||
for (iterator II = Succ->begin(), IE = Succ->end(); II != IE; ++II) {
|
||||
PHINode *PN = dyn_cast<PHINode>(II);
|
||||
if (!PN)
|
||||
break;
|
||||
int i;
|
||||
while ((i = PN->getBasicBlockIndex(this)) >= 0)
|
||||
PN->setIncomingBlock(i, New);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if this basic block is a landing pad. I.e., it's
|
||||
/// the destination of the 'unwind' edge of an invoke instruction.
|
||||
bool BasicBlock::isLandingPad() const {
|
||||
return isa<LandingPadInst>(getFirstNonPHI());
|
||||
}
|
||||
|
||||
/// Return the landingpad instruction associated with the landing pad.
|
||||
const LandingPadInst *BasicBlock::getLandingPadInst() const {
|
||||
return dyn_cast<LandingPadInst>(getFirstNonPHI());
|
||||
}
|
||||
|
||||
Optional<uint64_t> BasicBlock::getIrrLoopHeaderWeight() const {
|
||||
const TerminatorInst *TI = getTerminator();
|
||||
if (MDNode *MDIrrLoopHeader =
|
||||
TI->getMetadata(LLVMContext::MD_irr_loop)) {
|
||||
MDString *MDName = cast<MDString>(MDIrrLoopHeader->getOperand(0));
|
||||
if (MDName->getString().equals("loop_header_weight")) {
|
||||
auto *CI = mdconst::extract<ConstantInt>(MDIrrLoopHeader->getOperand(1));
|
||||
return Optional<uint64_t>(CI->getValue().getZExtValue());
|
||||
}
|
||||
}
|
||||
return Optional<uint64_t>();
|
||||
}
|
63
external/llvm/lib/IR/CMakeLists.txt
vendored
63
external/llvm/lib/IR/CMakeLists.txt
vendored
@ -1,63 +0,0 @@
|
||||
set(LLVM_TARGET_DEFINITIONS AttributesCompatFunc.td)
|
||||
tablegen(LLVM AttributesCompatFunc.inc -gen-attrs)
|
||||
add_public_tablegen_target(AttributeCompatFuncTableGen)
|
||||
|
||||
add_llvm_library(LLVMCore
|
||||
AsmWriter.cpp
|
||||
Attributes.cpp
|
||||
AutoUpgrade.cpp
|
||||
BasicBlock.cpp
|
||||
Comdat.cpp
|
||||
ConstantFold.cpp
|
||||
ConstantRange.cpp
|
||||
Constants.cpp
|
||||
Core.cpp
|
||||
DIBuilder.cpp
|
||||
DataLayout.cpp
|
||||
DebugInfo.cpp
|
||||
DebugInfoMetadata.cpp
|
||||
DebugLoc.cpp
|
||||
DiagnosticHandler.cpp
|
||||
DiagnosticInfo.cpp
|
||||
DiagnosticPrinter.cpp
|
||||
Dominators.cpp
|
||||
Function.cpp
|
||||
GVMaterializer.cpp
|
||||
Globals.cpp
|
||||
IRBuilder.cpp
|
||||
IRPrintingPasses.cpp
|
||||
InlineAsm.cpp
|
||||
Instruction.cpp
|
||||
Instructions.cpp
|
||||
IntrinsicInst.cpp
|
||||
LLVMContext.cpp
|
||||
LLVMContextImpl.cpp
|
||||
LegacyPassManager.cpp
|
||||
MDBuilder.cpp
|
||||
Mangler.cpp
|
||||
Metadata.cpp
|
||||
Module.cpp
|
||||
ModuleSummaryIndex.cpp
|
||||
Operator.cpp
|
||||
OptBisect.cpp
|
||||
Pass.cpp
|
||||
PassManager.cpp
|
||||
PassRegistry.cpp
|
||||
SafepointIRVerifier.cpp
|
||||
ProfileSummary.cpp
|
||||
Statepoint.cpp
|
||||
Type.cpp
|
||||
TypeFinder.cpp
|
||||
Use.cpp
|
||||
User.cpp
|
||||
Value.cpp
|
||||
ValueSymbolTable.cpp
|
||||
ValueTypes.cpp
|
||||
Verifier.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/IR
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
24
external/llvm/lib/IR/Comdat.cpp
vendored
24
external/llvm/lib/IR/Comdat.cpp
vendored
@ -1,24 +0,0 @@
|
||||
//===- Comdat.cpp - Implement Metadata classes ----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Comdat class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/Comdat.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
Comdat::Comdat(Comdat &&C) : Name(C.Name), SK(C.SK) {}
|
||||
|
||||
Comdat::Comdat() = default;
|
||||
|
||||
StringRef Comdat::getName() const { return Name->first(); }
|
2348
external/llvm/lib/IR/ConstantFold.cpp
vendored
2348
external/llvm/lib/IR/ConstantFold.cpp
vendored
File diff suppressed because it is too large
Load Diff
56
external/llvm/lib/IR/ConstantFold.h
vendored
56
external/llvm/lib/IR/ConstantFold.h
vendored
@ -1,56 +0,0 @@
|
||||
//===-- ConstantFolding.h - Internal Constant Folding Interface -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the (internal) constant folding interfaces for LLVM. These
|
||||
// interfaces are used by the ConstantExpr::get* methods to automatically fold
|
||||
// constants when possible.
|
||||
//
|
||||
// These operators may return a null object if they don't know how to perform
|
||||
// the specified operation on the specified constant types.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_IR_CONSTANTFOLD_H
|
||||
#define LLVM_LIB_IR_CONSTANTFOLD_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> class ArrayRef;
|
||||
class Value;
|
||||
class Constant;
|
||||
class Type;
|
||||
|
||||
// Constant fold various types of instruction...
|
||||
Constant *ConstantFoldCastInstruction(
|
||||
unsigned opcode, ///< The opcode of the cast
|
||||
Constant *V, ///< The source constant
|
||||
Type *DestTy ///< The destination type
|
||||
);
|
||||
Constant *ConstantFoldSelectInstruction(Constant *Cond,
|
||||
Constant *V1, Constant *V2);
|
||||
Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx);
|
||||
Constant *ConstantFoldInsertElementInstruction(Constant *Val, Constant *Elt,
|
||||
Constant *Idx);
|
||||
Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
|
||||
Constant *Mask);
|
||||
Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
|
||||
ArrayRef<unsigned> Idxs);
|
||||
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
|
||||
ArrayRef<unsigned> Idxs);
|
||||
Constant *ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1,
|
||||
Constant *V2);
|
||||
Constant *ConstantFoldCompareInstruction(unsigned short predicate,
|
||||
Constant *C1, Constant *C2);
|
||||
Constant *ConstantFoldGetElementPtr(Type *Ty, Constant *C, bool InBounds,
|
||||
Optional<unsigned> InRangeIndex,
|
||||
ArrayRef<Value *> Idxs);
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
1048
external/llvm/lib/IR/ConstantRange.cpp
vendored
1048
external/llvm/lib/IR/ConstantRange.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
dccba779deb354b9f50275a0e978a03bd8c40f68
|
703
external/llvm/lib/IR/ConstantsContext.h
vendored
703
external/llvm/lib/IR/ConstantsContext.h
vendored
File diff suppressed because it is too large
Load Diff
1
external/llvm/lib/IR/Core.cpp.REMOVED.git-id
vendored
1
external/llvm/lib/IR/Core.cpp.REMOVED.git-id
vendored
@ -1 +0,0 @@
|
||||
d3c33edec18678ed71afabbb48c58ea7cf935cd9
|
918
external/llvm/lib/IR/DIBuilder.cpp
vendored
918
external/llvm/lib/IR/DIBuilder.cpp
vendored
File diff suppressed because it is too large
Load Diff
786
external/llvm/lib/IR/DataLayout.cpp
vendored
786
external/llvm/lib/IR/DataLayout.cpp
vendored
File diff suppressed because it is too large
Load Diff
755
external/llvm/lib/IR/DebugInfo.cpp
vendored
755
external/llvm/lib/IR/DebugInfo.cpp
vendored
File diff suppressed because it is too large
Load Diff
886
external/llvm/lib/IR/DebugInfoMetadata.cpp
vendored
886
external/llvm/lib/IR/DebugInfoMetadata.cpp
vendored
File diff suppressed because it is too large
Load Diff
133
external/llvm/lib/IR/DebugLoc.cpp
vendored
133
external/llvm/lib/IR/DebugLoc.cpp
vendored
@ -1,133 +0,0 @@
|
||||
//===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "LLVMContextImpl.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
using namespace llvm;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DebugLoc Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
DebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {}
|
||||
DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}
|
||||
|
||||
DILocation *DebugLoc::get() const {
|
||||
return cast_or_null<DILocation>(Loc.get());
|
||||
}
|
||||
|
||||
unsigned DebugLoc::getLine() const {
|
||||
assert(get() && "Expected valid DebugLoc");
|
||||
return get()->getLine();
|
||||
}
|
||||
|
||||
unsigned DebugLoc::getCol() const {
|
||||
assert(get() && "Expected valid DebugLoc");
|
||||
return get()->getColumn();
|
||||
}
|
||||
|
||||
MDNode *DebugLoc::getScope() const {
|
||||
assert(get() && "Expected valid DebugLoc");
|
||||
return get()->getScope();
|
||||
}
|
||||
|
||||
DILocation *DebugLoc::getInlinedAt() const {
|
||||
assert(get() && "Expected valid DebugLoc");
|
||||
return get()->getInlinedAt();
|
||||
}
|
||||
|
||||
MDNode *DebugLoc::getInlinedAtScope() const {
|
||||
return cast<DILocation>(Loc)->getInlinedAtScope();
|
||||
}
|
||||
|
||||
DebugLoc DebugLoc::getFnDebugLoc() const {
|
||||
// FIXME: Add a method on \a DILocation that does this work.
|
||||
const MDNode *Scope = getInlinedAtScope();
|
||||
if (auto *SP = getDISubprogram(Scope))
|
||||
return DebugLoc::get(SP->getScopeLine(), 0, SP);
|
||||
|
||||
return DebugLoc();
|
||||
}
|
||||
|
||||
DebugLoc DebugLoc::get(unsigned Line, unsigned Col, const MDNode *Scope,
|
||||
const MDNode *InlinedAt) {
|
||||
// If no scope is available, this is an unknown location.
|
||||
if (!Scope)
|
||||
return DebugLoc();
|
||||
|
||||
return DILocation::get(Scope->getContext(), Line, Col,
|
||||
const_cast<MDNode *>(Scope),
|
||||
const_cast<MDNode *>(InlinedAt));
|
||||
}
|
||||
|
||||
DebugLoc DebugLoc::appendInlinedAt(DebugLoc DL, DILocation *InlinedAt,
|
||||
LLVMContext &Ctx,
|
||||
DenseMap<const MDNode *, MDNode *> &Cache,
|
||||
bool ReplaceLast) {
|
||||
SmallVector<DILocation *, 3> InlinedAtLocations;
|
||||
DILocation *Last = InlinedAt;
|
||||
DILocation *CurInlinedAt = DL;
|
||||
|
||||
// Gather all the inlined-at nodes.
|
||||
while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
|
||||
// Skip any we've already built nodes for.
|
||||
if (auto *Found = Cache[IA]) {
|
||||
Last = cast<DILocation>(Found);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ReplaceLast && !IA->getInlinedAt())
|
||||
break;
|
||||
InlinedAtLocations.push_back(IA);
|
||||
CurInlinedAt = IA;
|
||||
}
|
||||
|
||||
// Starting from the top, rebuild the nodes to point to the new inlined-at
|
||||
// location (then rebuilding the rest of the chain behind it) and update the
|
||||
// map of already-constructed inlined-at nodes.
|
||||
for (const DILocation *MD : reverse(InlinedAtLocations))
|
||||
Cache[MD] = Last = DILocation::getDistinct(
|
||||
Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
|
||||
|
||||
return Last;
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
LLVM_DUMP_METHOD void DebugLoc::dump() const {
|
||||
if (!Loc)
|
||||
return;
|
||||
|
||||
dbgs() << getLine();
|
||||
if (getCol() != 0)
|
||||
dbgs() << ',' << getCol();
|
||||
if (DebugLoc InlinedAtDL = DebugLoc(getInlinedAt())) {
|
||||
dbgs() << " @ ";
|
||||
InlinedAtDL.dump();
|
||||
} else
|
||||
dbgs() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
void DebugLoc::print(raw_ostream &OS) const {
|
||||
if (!Loc)
|
||||
return;
|
||||
|
||||
// Print source line info.
|
||||
auto *Scope = cast<DIScope>(getScope());
|
||||
OS << Scope->getFilename();
|
||||
OS << ':' << getLine();
|
||||
if (getCol() != 0)
|
||||
OS << ':' << getCol();
|
||||
|
||||
if (DebugLoc InlinedAtDL = getInlinedAt()) {
|
||||
OS << " @[ ";
|
||||
InlinedAtDL.print(OS);
|
||||
OS << " ]";
|
||||
}
|
||||
}
|
91
external/llvm/lib/IR/DiagnosticHandler.cpp
vendored
91
external/llvm/lib/IR/DiagnosticHandler.cpp
vendored
@ -1,91 +0,0 @@
|
||||
//===- DiagnosticHandler.h - DiagnosticHandler class for LLVM -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "llvm/IR/DiagnosticHandler.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief Regular expression corresponding to the value given in one of the
|
||||
/// -pass-remarks* command line flags. Passes whose name matches this regexp
|
||||
/// will emit a diagnostic when calling the associated diagnostic function
|
||||
/// (emitOptimizationRemark, emitOptimizationRemarkMissed or
|
||||
/// emitOptimizationRemarkAnalysis).
|
||||
struct PassRemarksOpt {
|
||||
std::shared_ptr<Regex> Pattern;
|
||||
|
||||
void operator=(const std::string &Val) {
|
||||
// Create a regexp object to match pass names for emitOptimizationRemark.
|
||||
if (!Val.empty()) {
|
||||
Pattern = std::make_shared<Regex>(Val);
|
||||
std::string RegexError;
|
||||
if (!Pattern->isValid(RegexError))
|
||||
report_fatal_error("Invalid regular expression '" + Val +
|
||||
"' in -pass-remarks: " + RegexError,
|
||||
false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static PassRemarksOpt PassRemarksPassedOptLoc;
|
||||
static PassRemarksOpt PassRemarksMissedOptLoc;
|
||||
static PassRemarksOpt PassRemarksAnalysisOptLoc;
|
||||
|
||||
// -pass-remarks
|
||||
// Command line flag to enable emitOptimizationRemark()
|
||||
static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarks(
|
||||
"pass-remarks", cl::value_desc("pattern"),
|
||||
cl::desc("Enable optimization remarks from passes whose name match "
|
||||
"the given regular expression"),
|
||||
cl::Hidden, cl::location(PassRemarksPassedOptLoc), cl::ValueRequired,
|
||||
cl::ZeroOrMore);
|
||||
|
||||
// -pass-remarks-missed
|
||||
// Command line flag to enable emitOptimizationRemarkMissed()
|
||||
static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
|
||||
"pass-remarks-missed", cl::value_desc("pattern"),
|
||||
cl::desc("Enable missed optimization remarks from passes whose name match "
|
||||
"the given regular expression"),
|
||||
cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
|
||||
cl::ZeroOrMore);
|
||||
|
||||
// -pass-remarks-analysis
|
||||
// Command line flag to enable emitOptimizationRemarkAnalysis()
|
||||
static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
|
||||
PassRemarksAnalysis(
|
||||
"pass-remarks-analysis", cl::value_desc("pattern"),
|
||||
cl::desc(
|
||||
"Enable optimization analysis remarks from passes whose name match "
|
||||
"the given regular expression"),
|
||||
cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
|
||||
cl::ZeroOrMore);
|
||||
}
|
||||
|
||||
bool DiagnosticHandler::isAnalysisRemarkEnabled(StringRef PassName) const {
|
||||
return (PassRemarksAnalysisOptLoc.Pattern &&
|
||||
PassRemarksAnalysisOptLoc.Pattern->match(PassName));
|
||||
}
|
||||
bool DiagnosticHandler::isMissedOptRemarkEnabled(StringRef PassName) const {
|
||||
return (PassRemarksMissedOptLoc.Pattern &&
|
||||
PassRemarksMissedOptLoc.Pattern->match(PassName));
|
||||
}
|
||||
bool DiagnosticHandler::isPassedOptRemarkEnabled(StringRef PassName) const {
|
||||
return (PassRemarksPassedOptLoc.Pattern &&
|
||||
PassRemarksPassedOptLoc.Pattern->match(PassName));
|
||||
}
|
||||
|
||||
bool DiagnosticHandler::isAnyRemarkEnabled() const {
|
||||
return (PassRemarksPassedOptLoc.Pattern || PassRemarksMissedOptLoc.Pattern ||
|
||||
PassRemarksAnalysisOptLoc.Pattern);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user