Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1 +0,0 @@
0fafe82404e4db8f2036a55bcafb157a27a2cada

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
include "llvm/IR/Attributes.td"

View File

@ -1 +0,0 @@
c56a022c6705e846e493c2bc56c0ea12b7bf3035

View File

@ -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>();
}

View File

@ -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
)

View File

@ -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(); }

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
dccba779deb354b9f50275a0e978a03bd8c40f68

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
d3c33edec18678ed71afabbb48c58ea7cf935cd9

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 << " ]";
}
}

View File

@ -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