#ifndef LLVM_ANALYSIS_CGSCCPASSMANAGER_H
#define LLVM_ANALYSIS_CGSCCPASSMANAGER_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PriorityWorklist.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <utility>
namespace llvm {
+struct CGSCCUpdateResult;
+class Module;
+
// Allow debug logging in this inline function.
#define DEBUG_TYPE "cgscc"
-struct CGSCCUpdateResult;
-
/// Extern template declaration for the analysis set for this IR unit.
extern template class AllAnalysesOn<LazyCallGraph::SCC>;
extern template class AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
+
/// \brief The CGSCC analysis manager.
///
/// See the documentation for the AnalysisManager template for detail
-/// documentation. This typedef serves as a convenient way to refer to this
+/// documentation. This type serves as a convenient way to refer to this
/// construct in the adaptors and proxies used to integrate this into the larger
/// pass manager infrastructure.
-typedef AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>
- CGSCCAnalysisManager;
+using CGSCCAnalysisManager =
+ AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
// Explicit specialization and instantiation declarations for the pass manager.
// See the comments on the definition of the specialization for details on how
///
/// See the documentation for the PassManager template for details. It runs
/// a sequence of SCC passes over each SCC that the manager is run over. This
-/// typedef serves as a convenient way to refer to this construct.
-typedef PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
- CGSCCUpdateResult &>
- CGSCCPassManager;
+/// type serves as a convenient way to refer to this construct.
+using CGSCCPassManager =
+ PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
+ CGSCCUpdateResult &>;
/// An explicit specialization of the require analysis template pass.
template <typename AnalysisT>
};
/// A proxy from a \c CGSCCAnalysisManager to a \c Module.
-typedef InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>
- CGSCCAnalysisManagerModuleProxy;
+using CGSCCAnalysisManagerModuleProxy =
+ InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
/// We need a specialized result for the \c CGSCCAnalysisManagerModuleProxy so
/// it can have access to the call graph in order to walk all the SCCs when
extern template class OuterAnalysisManagerProxy<
ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph &>;
+
/// A proxy from a \c ModuleAnalysisManager to an \c SCC.
-typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC,
- LazyCallGraph &>
- ModuleAnalysisManagerCGSCCProxy;
+using ModuleAnalysisManagerCGSCCProxy =
+ OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC,
+ LazyCallGraph &>;
/// Support structure for SCC passes to communicate updates the call graph back
/// to the CGSCC pass manager infrsatructure.
public:
explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass)
: Pass(std::move(Pass)) {}
+
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
ModuleToPostOrderCGSCCPassAdaptor(
const ModuleToPostOrderCGSCCPassAdaptor &Arg)
: Pass(Arg.Pass) {}
+
ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
: Pass(std::move(Arg.Pass)) {}
+
friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
ModuleToPostOrderCGSCCPassAdaptor &RHS) {
- using std::swap;
- swap(LHS.Pass, RHS.Pass);
+ std::swap(LHS.Pass, RHS.Pass);
}
+
ModuleToPostOrderCGSCCPassAdaptor &
operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
swap(*this, RHS);
// Push the initial SCCs in reverse post-order as we'll pop off the the
// back and so see this in post-order.
- for (LazyCallGraph::SCC &C : reverse(*RC))
+ for (LazyCallGraph::SCC &C : llvm::reverse(*RC))
CWorklist.insert(&C);
do {
private:
friend AnalysisInfoMixin<FunctionAnalysisManagerCGSCCProxy>;
+
static AnalysisKey Key;
};
extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
+
/// A proxy from a \c CGSCCAnalysisManager to a \c Function.
-typedef OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>
- CGSCCAnalysisManagerFunctionProxy;
+using CGSCCAnalysisManagerFunctionProxy =
+ OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
/// Helper to update the call graph after running a function pass.
///
public:
explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass)
: Pass(std::move(Pass)) {}
+
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
: Pass(Arg.Pass) {}
+
CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
: Pass(std::move(Arg.Pass)) {}
+
friend void swap(CGSCCToFunctionPassAdaptor &LHS,
CGSCCToFunctionPassAdaptor &RHS) {
- using std::swap;
- swap(LHS.Pass, RHS.Pass);
+ std::swap(LHS.Pass, RHS.Pass);
}
+
CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
swap(*this, RHS);
return *this;
// so iterate to process this devirtualization site.
return true;
};
- bool Devirt = any_of(CallHandles, IsDevirtualizedHandle);
+ bool Devirt = llvm::any_of(CallHandles, IsDevirtualizedHandle);
// Rescan to build up a new set of handles and count how many direct
// calls remain. If we decide to iterate, this also sets up the input to
// Clear out the debug logging macro.
#undef DEBUG_TYPE
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_CGSCCPASSMANAGER_H
#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
-#include "llvm/Analysis/CallGraph.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Pass.h"
-#include "llvm/PassSupport.h"
+#include <vector>
namespace llvm {
-class CallGraphNode;
class CallGraph;
-class PMStack;
+class CallGraphNode;
class CallGraphSCC;
+class PMStack;
class CallGraphSCCPass : public Pass {
public:
/// createPrinterPass - Get a pass that prints the Module
/// corresponding to a CallGraph.
- Pass *createPrinterPass(raw_ostream &O,
+ Pass *createPrinterPass(raw_ostream &OS,
const std::string &Banner) const override;
using llvm::Pass::doInitialization;
///
/// SCC passes that add or delete functions to the SCC are required to update
/// the SCC list, otherwise stale pointers may be dereferenced.
- ///
virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
/// doFinalization - This method is called after the SCC's of the program has
class CallGraphSCC {
const CallGraph &CG; // The call graph for this SCC.
void *Context; // The CGPassManager object that is vending this.
- std::vector<CallGraphNode*> Nodes;
+ std::vector<CallGraphNode *> Nodes;
public:
CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {}
/// Old node has been deleted, and New is to be used in its place.
void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
- typedef std::vector<CallGraphNode *>::const_iterator iterator;
+ using iterator = std::vector<CallGraphNode *>::const_iterator;
+
iterator begin() const { return Nodes.begin(); }
iterator end() const { return Nodes.end(); }
class DummyCGSCCPass : public CallGraphSCCPass {
public:
static char ID;
+
DummyCGSCCPass() : CallGraphSCCPass(ID) {
PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeDummyCGSCCPassPass(Registry);
- };
+ }
+
bool runOnSCC(CallGraphSCC &SCC) override { return false; }
+
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <iterator>
#define DEBUG_TYPE "cgscc"
return false;
}
-} // End llvm namespace
+} // end namespace llvm
/// When a new SCC is created for the graph and there might be function
/// analysis results cached for the functions now in that SCC two forms of
}
}
-namespace {
/// Helper function to update both the \c CGSCCAnalysisManager \p AM and the \c
/// CGSCCPassManager's \c CGSCCUpdateResult \p UR based on a range of newly
/// added SCCs.
/// This function returns the SCC containing \p N. This will be either \p C if
/// no new SCCs have been split out, or it will be the new SCC containing \p N.
template <typename SCCRangeT>
-LazyCallGraph::SCC *
+static LazyCallGraph::SCC *
incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,
LazyCallGraph::Node &N, LazyCallGraph::SCC *C,
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
- typedef LazyCallGraph::SCC SCC;
+ using SCC = LazyCallGraph::SCC;
if (NewSCCRange.begin() == NewSCCRange.end())
return C;
if (NeedFAMProxy)
updateNewSCCFunctionAnalyses(*C, G, AM);
- for (SCC &NewC :
- reverse(make_range(std::next(NewSCCRange.begin()), NewSCCRange.end()))) {
+ for (SCC &NewC : llvm::reverse(make_range(std::next(NewSCCRange.begin()),
+ NewSCCRange.end()))) {
assert(C != &NewC && "No need to re-visit the current SCC!");
assert(OldC != &NewC && "Already handled the original SCC!");
UR.CWorklist.insert(&NewC);
}
return C;
}
-}
LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N,
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
- typedef LazyCallGraph::Node Node;
- typedef LazyCallGraph::Edge Edge;
- typedef LazyCallGraph::SCC SCC;
- typedef LazyCallGraph::RefSCC RefSCC;
+ using Node = LazyCallGraph::Node;
+ using Edge = LazyCallGraph::Edge;
+ using SCC = LazyCallGraph::SCC;
+ using RefSCC = LazyCallGraph::RefSCC;
RefSCC &InitialRC = InitialC.getOuterRefSCC();
SCC *C = &InitialC;
// Now walk all references.
for (Instruction &I : instructions(F))
for (Value *Op : I.operand_values())
- if (Constant *C = dyn_cast<Constant>(Op))
+ if (auto *C = dyn_cast<Constant>(Op))
if (Visited.insert(C).second)
Worklist.push_back(C);
// "bottom" we will continue processing in the bottom-up walk.
assert(NewRefSCCs.front() == RC &&
"New current RefSCC not first in the returned list!");
- for (RefSCC *NewRC :
- reverse(make_range(std::next(NewRefSCCs.begin()), NewRefSCCs.end()))) {
+ for (RefSCC *NewRC : llvm::reverse(make_range(std::next(NewRefSCCs.begin()),
+ NewRefSCCs.end()))) {
assert(NewRC != RC && "Should not encounter the current RefSCC further "
"in the postorder list of new RefSCCs.");
UR.RCWorklist.insert(NewRC);
DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist: " << *C
<< "\n");
// Enqueue in reverse order as we pop off the back of the worklist.
- for (SCC &MovedC : reverse(make_range(RC->begin() + InitialSCCIndex,
- RC->begin() + NewSCCIndex))) {
+ for (SCC &MovedC : llvm::reverse(make_range(RC->begin() + InitialSCCIndex,
+ RC->begin() + NewSCCIndex))) {
UR.CWorklist.insert(&MovedC);
DEBUG(dbgs() << "Enqueuing a newly earlier in post-order SCC: "
<< MovedC << "\n");
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/CallGraph.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManagers.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/OptBisect.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <string>
+#include <utility>
+#include <vector>
+
using namespace llvm;
#define DEBUG_TYPE "cgscc-passmgr"
class CGPassManager : public ModulePass, public PMDataManager {
public:
static char ID;
- explicit CGPassManager()
- : ModulePass(ID), PMDataManager() { }
+
+ explicit CGPassManager() : ModulePass(ID), PMDataManager() {}
/// Execute all of the passes scheduled for execution. Keep track of
/// whether any of the passes modifies the module, and if so, return true.
char CGPassManager::ID = 0;
-
bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
CallGraph &CG, bool &CallGraphUpToDate,
bool &DevirtualizedCall) {
return Changed;
}
-
assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
"Invalid CGPassManager member");
FPPassManager *FPP = (FPPassManager*)P;
return Changed;
}
-
/// Scan the functions in the specified CFG and resync the
/// callgraph with the call sites found in it. This is used after
/// FunctionPasses have potentially munged the callgraph, and can be used after
/// meaning it turned an indirect call into a direct call. This happens when
/// a function pass like GVN optimizes away stuff feeding the indirect call.
/// This never happens in checking mode.
-///
bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
bool CheckingMode) {
DenseMap<Value*, CallGraphNode*> CallSites;
return Changed;
}
-
/// Initialize CG
bool CGPassManager::doInitialization(CallGraph &CG) {
bool Changed = false;
CGI->ReplaceNode(Old, New);
}
-
//===----------------------------------------------------------------------===//
// CallGraphSCCPass Implementation
//===----------------------------------------------------------------------===//
AU.addPreserved<CallGraphWrapperPass>();
}
-
//===----------------------------------------------------------------------===//
// PrintCallGraphPass Implementation
//===----------------------------------------------------------------------===//
namespace {
+
/// PrintCallGraphPass - Print a Module corresponding to a call graph.
///
class PrintCallGraphPass : public CallGraphSCCPass {
std::string Banner;
- raw_ostream &Out; // raw_ostream to print on.
+ raw_ostream &OS; // raw_ostream to print on.
public:
static char ID;
- PrintCallGraphPass(const std::string &B, raw_ostream &o)
- : CallGraphSCCPass(ID), Banner(B), Out(o) {}
+
+ PrintCallGraphPass(const std::string &B, raw_ostream &OS)
+ : CallGraphSCCPass(ID), Banner(B), OS(OS) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
auto PrintBannerOnce = [&] () {
if (BannerPrinted)
return;
- Out << Banner;
+ OS << Banner;
BannerPrinted = true;
};
for (CallGraphNode *CGN : SCC) {
if (Function *F = CGN->getFunction()) {
if (!F->isDeclaration() && isFunctionInPrintList(F->getName())) {
PrintBannerOnce();
- F->print(Out);
+ F->print(OS);
}
- } else if (llvm::isFunctionInPrintList("*")) {
+ } else if (isFunctionInPrintList("*")) {
PrintBannerOnce();
- Out << "\nPrinting <null> Function\n";
+ OS << "\nPrinting <null> Function\n";
}
}
return false;
char PrintCallGraphPass::ID = 0;
-Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &O,
+Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &OS,
const std::string &Banner) const {
- return new PrintCallGraphPass(Banner, O);
+ return new PrintCallGraphPass(Banner, OS);
}
bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
}
char DummyCGSCCPass::ID = 0;
+
INITIALIZE_PASS(DummyCGSCCPass, "DummyCGSCCPass", "DummyCGSCCPass", false,
false)
-//===-- AMDGPUAnnotateKernelFeaturesPass.cpp ------------------------------===//
+//===- AMDGPUAnnotateKernelFeaturesPass.cpp -------------------------------===//
//
// The LLVM Compiler Infrastructure
//
#include "AMDGPU.h"
#include "AMDGPUSubtarget.h"
+#include "Utils/AMDGPUBaseInfo.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Use.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetMachine.h"
#define DEBUG_TYPE "amdgpu-annotate-kernel-features"
bool doInitialization(CallGraph &CG) override;
bool runOnSCC(CallGraphSCC &SCC) override;
+
StringRef getPassName() const override {
return "AMDGPU Annotate Kernel Features";
}
AMDGPUAS AS);
};
-}
+} // end anonymous namespace
char AMDGPUAnnotateKernelFeatures::ID = 0;
Changed |= addFeatureAttributes(*F);
}
-
return Changed;
}
// coroutine.
//===----------------------------------------------------------------------===//
+#include "CoroInstr.h"
#include "CoroInternal.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
-#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <initializer_list>
+#include <iterator>
using namespace llvm;
// Assumes that all the functions have the same signature.
static void setCoroInfo(Function &F, CoroBeginInst *CoroBegin,
std::initializer_list<Function *> Fns) {
-
SmallVector<Constant *, 4> Args(Fns.begin(), Fns.end());
assert(!Args.empty());
Function *Part = *Fns.begin();
// Store addresses of Resume/Destroy/Cleanup functions in the coroutine frame.
static void updateCoroFrame(coro::Shape &Shape, Function *ResumeFn,
Function *DestroyFn, Function *CleanupFn) {
-
IRBuilder<> Builder(Shape.FramePtr->getNextNode());
auto *ResumeAddr = Builder.CreateConstInBoundsGEP2_32(
Shape.FrameTy, Shape.FramePtr, 0, coro::Shape::ResumeField,
static void postSplitCleanup(Function &F) {
removeUnreachableBlocks(F);
- llvm::legacy::FunctionPassManager FPM(F.getParent());
+ legacy::FunctionPassManager FPM(F.getParent());
FPM.add(createVerifierPass());
FPM.add(createSCCPPass());
// Set musttail on those that are followed by a ret instruction.
for (CallInst *Call : Resumes)
if (simplifyTerminatorLeadingToRet(Call->getNextNode())) {
- Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
+ Call->setTailCallKind(CallInst::TCK_MustTail);
changed = true;
}
size_t I = 0, N = S.size();
if (N == 0)
return;
- for (;;) {
+ while (true) {
if (simplifySuspendPoint(S[I], Shape.CoroBegin)) {
if (--N == I)
break;
struct CoroSplit : public CallGraphSCCPass {
static char ID; // Pass identification, replacement for typeid
+
CoroSplit() : CallGraphSCCPass(ID) {
initializeCoroSplitPass(*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
CallGraphSCCPass::getAnalysisUsage(AU);
}
+
StringRef getPassName() const override { return "Coroutine Splitting"; }
};
-}
+
+} // end anonymous namespace
char CoroSplit::ID = 0;
+
INITIALIZE_PASS(
CoroSplit, "coro-split",
"Split coroutine into a set of functions driving its state machine", false,
-//===-- Coroutines.cpp ----------------------------------------------------===//
+//===- Coroutines.cpp -----------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
// This file implements the common infrastructure for Coroutine Passes.
+//
//===----------------------------------------------------------------------===//
+#include "CoroInstr.h"
#include "CoroInternal.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/InitializePasses.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Transforms/Coroutines.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/Local.h"
+#include <cassert>
+#include <cstddef>
+#include <utility>
using namespace llvm;
// that names are intrinsic names.
bool coro::declaresIntrinsics(Module &M,
std::initializer_list<StringRef> List) {
-
for (StringRef Name : List) {
assert(isCoroutineIntrinsicName(Name) && "not a coroutine intrinsic");
if (M.getNamedValue(Name))
-//===-- LoopUnswitch.cpp - Hoist loop-invariant conditionals in loop ------===//
+//===- LoopUnswitch.cpp - Hoist loop-invariant conditionals in loop -------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
-#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/DivergenceAnalysis.h"
-#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/BranchProbability.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
+#include <cassert>
#include <map>
#include <set>
+#include <tuple>
+#include <utility>
+#include <vector>
+
using namespace llvm;
#define DEBUG_TYPE "loop-unswitch"
namespace {
class LUAnalysisCache {
-
- typedef DenseMap<const SwitchInst*, SmallPtrSet<const Value *, 8> >
- UnswitchedValsMap;
-
- typedef UnswitchedValsMap::iterator UnswitchedValsIt;
+ using UnswitchedValsMap =
+ DenseMap<const SwitchInst *, SmallPtrSet<const Value *, 8>>;
+ using UnswitchedValsIt = UnswitchedValsMap::iterator;
struct LoopProperties {
unsigned CanBeUnswitchedCount;
// Here we use std::map instead of DenseMap, since we need to keep valid
// LoopProperties pointer for current loop for better performance.
- typedef std::map<const Loop*, LoopProperties> LoopPropsMap;
- typedef LoopPropsMap::iterator LoopPropsMapIt;
+ using LoopPropsMap = std::map<const Loop *, LoopProperties>;
+ using LoopPropsMapIt = LoopPropsMap::iterator;
LoopPropsMap LoopsProperties;
- UnswitchedValsMap *CurLoopInstructions;
- LoopProperties *CurrentLoopProperties;
+ UnswitchedValsMap *CurLoopInstructions = nullptr;
+ LoopProperties *CurrentLoopProperties = nullptr;
// A loop unswitching with an estimated cost above this threshold
// is not performed. MaxSize is turned into unswitching quota for
unsigned MaxSize;
public:
- LUAnalysisCache()
- : CurLoopInstructions(nullptr), CurrentLoopProperties(nullptr),
- MaxSize(Threshold) {}
+ LUAnalysisCache() : MaxSize(Threshold) {}
// Analyze loop. Check its size, calculate is it possible to unswitch
// it. Returns true if we can unswitch this loop.
LUAnalysisCache BranchesInfo;
bool OptimizeForSize;
- bool redoLoop;
+ bool redoLoop = false;
- Loop *currentLoop;
- DominatorTree *DT;
- BasicBlock *loopHeader;
- BasicBlock *loopPreheader;
+ Loop *currentLoop = nullptr;
+ DominatorTree *DT = nullptr;
+ BasicBlock *loopHeader = nullptr;
+ BasicBlock *loopPreheader = nullptr;
bool SanitizeMemory;
LoopSafetyInfo SafetyInfo;
public:
static char ID; // Pass ID, replacement for typeid
- explicit LoopUnswitch(bool Os = false, bool hasBranchDivergence = false) :
- LoopPass(ID), OptimizeForSize(Os), redoLoop(false),
- currentLoop(nullptr), DT(nullptr), loopHeader(nullptr),
- loopPreheader(nullptr), hasBranchDivergence(hasBranchDivergence) {
+
+ explicit LoopUnswitch(bool Os = false, bool hasBranchDivergence = false)
+ : LoopPass(ID), OptimizeForSize(Os),
+ hasBranchDivergence(hasBranchDivergence) {
initializeLoopUnswitchPass(*PassRegistry::getPassRegistry());
- }
+ }
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
bool processCurrentLoop();
bool isUnreachableDueToPreviousUnswitching(BasicBlock *);
+
/// This transformation requires natural loop information & requires that
/// loop preheaders be inserted into the CFG.
///
}
private:
-
void releaseMemory() override {
BranchesInfo.forgetLoop(currentLoop);
}
Value *SimplifyInstructionWithNotEqual(Instruction *Inst, Value *Invariant,
Constant *Val);
};
-}
+
+} // end anonymous namespace
// Analyze loop. Check its size, calculate is it possible to unswitch
// it. Returns true if we can unswitch this loop.
bool LUAnalysisCache::countLoop(const Loop *L, const TargetTransformInfo &TTI,
AssumptionCache *AC) {
-
LoopPropsMapIt PropsIt;
bool Inserted;
std::tie(PropsIt, Inserted) =
// Clean all data related to given loop.
void LUAnalysisCache::forgetLoop(const Loop *L) {
-
LoopPropsMapIt LIt = LoopsProperties.find(L);
if (LIt != LoopsProperties.end()) {
// Note, that new loop data is stored inside the VMap.
void LUAnalysisCache::cloneData(const Loop *NewLoop, const Loop *OldLoop,
const ValueToValueMapTy &VMap) {
-
LoopProperties &NewLoopProps = LoopsProperties[NewLoop];
LoopProperties &OldLoopProps = *CurrentLoopProperties;
UnswitchedValsMap &Insts = OldLoopProps.UnswitchedVals;
}
char LoopUnswitch::ID = 0;
+
INITIALIZE_PASS_BEGIN(LoopUnswitch, "loop-unswitch", "Unswitch loops",
false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-//===-- llvm-stress.cpp - Generate random LL files to stress-test LLVM ----===//
+//===- llvm-stress.cpp - Generate random LL files to stress-test LLVM -----===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <random>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
#include <vector>
namespace llvm {
static cl::opt<unsigned> SeedCL("seed",
cl::desc("Seed used for randomness"), cl::init(0));
+
static cl::opt<unsigned> SizeCL("size",
cl::desc("The estimated size of the generated function (# of instrs)"),
cl::init(100));
+
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"),
cl::value_desc("filename"));
static LLVMContext Context;
namespace cl {
+
template <> class parser<Type*> final : public basic_parser<Type*> {
public:
parser(Option &O) : basic_parser(O) {}
StringRef getValueName() const override { return "IR scalar type"; }
};
-}
+} // end namespace cl
static cl::list<Type*> AdditionalScalarTypes("types", cl::CommaSeparated,
cl::desc("Additional IR scalar types "
"(always includes i1, i8, i16, i32, i64, float and double)"));
namespace {
+
/// A utility class to provide a pseudo-random number generator which is
/// the same across all platforms. This is somewhat close to the libc
/// implementation. Note: This is not a cryptographically secure pseudorandom
}
/// Make this like a C++11 random device
- typedef uint32_t result_type;
+ using result_type = uint32_t ;
+
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 0x7ffff; }
+
uint32_t operator()() {
uint32_t Val = Rand();
assert(Val <= max() && "Random value out of range");
/// modifying and adding new random instructions.
struct Modifier {
/// Used to store the randomly generated values.
- typedef std::vector<Value*> PieceTable;
+ using PieceTable = std::vector<Value *>;
public:
/// C'tor
- Modifier(BasicBlock *Block, PieceTable *PT, Random *R):
- BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {}
+ Modifier(BasicBlock *Block, PieceTable *PT, Random *R)
+ : BB(Block), PT(PT), Ran(R), Context(BB->getContext()) {}
/// virtual D'tor to silence warnings.
- virtual ~Modifier() {}
+ virtual ~Modifier() = default;
/// Add a new instruction.
virtual void Act() = 0;
+
/// Add N new instructions,
virtual void ActN(unsigned n) {
for (unsigned i=0; i<n; ++i)
/// Basic block to populate
BasicBlock *BB;
+
/// Value table
PieceTable *PT;
+
/// Random number generator
Random *Ran;
+
/// Context
LLVMContext &Context;
};
struct LoadModifier: public Modifier {
- LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
+ LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
+
void Act() override {
// Try to use predefined pointers. If non-exist, use undef pointer value;
Value *Ptr = getRandomPointerValue();
};
struct StoreModifier: public Modifier {
- StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
+ StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
+
void Act() override {
// Try to use predefined pointers. If non-exist, use undef pointer value;
Value *Ptr = getRandomPointerValue();
};
struct BinModifier: public Modifier {
- BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
+ BinModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
void Act() override {
Value *Val0 = getRandomVal();
if (Val0->getType()->getScalarSizeInBits() == 1)
return;
-
bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy();
Instruction* Term = BB->getTerminator();
unsigned R = getRandom() % (isFloat ? 7 : 13);
/// Generate constant values.
struct ConstModifier: public Modifier {
- ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
+ ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
+
void Act() override {
Type *Ty = pickType();
};
struct AllocaModifier: public Modifier {
- AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){}
+ AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
void Act() override {
Type *Tp = pickType();
};
struct ExtractElementModifier: public Modifier {
- ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R):
- Modifier(BB, PT, R) {}
+ ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
void Act() override {
Value *Val0 = getRandomVectorValue();
};
struct ShuffModifier: public Modifier {
- ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
- void Act() override {
+ ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
+ void Act() override {
Value *Val0 = getRandomVectorValue();
Value *Val1 = getRandomValue(Val0->getType());
};
struct InsertElementModifier: public Modifier {
- InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R):
- Modifier(BB, PT, R) {}
+ InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
void Act() override {
Value *Val0 = getRandomVectorValue();
"I", BB->getTerminator());
return PT->push_back(V);
}
-
};
struct CastModifier: public Modifier {
- CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
- void Act() override {
+ CastModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
+ void Act() override {
Value *V = getRandomVal();
Type *VTy = V->getType();
Type *DestTy = pickScalarType();
return PT->push_back(
new SIToFPInst(V, DestTy, "FC", BB->getTerminator()));
return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator()));
-
}
// Both floats.
// for which there is no defined conversion. So do nothing.
}
}
-
};
struct SelectModifier: public Modifier {
- SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R):
- Modifier(BB, PT, R) {}
+ SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
void Act() override {
// Try a bunch of different select configuration until a valid one is found.
- Value *Val0 = getRandomVal();
- Value *Val1 = getRandomValue(Val0->getType());
+ Value *Val0 = getRandomVal();
+ Value *Val1 = getRandomValue(Val0->getType());
- Type *CondTy = Type::getInt1Ty(Context);
+ Type *CondTy = Type::getInt1Ty(Context);
- // If the value type is a vector, and we allow vector select, then in 50%
- // of the cases generate a vector select.
- if (Val0->getType()->isVectorTy() && (getRandom() % 1)) {
- unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements();
- CondTy = VectorType::get(CondTy, NumElem);
- }
+ // If the value type is a vector, and we allow vector select, then in 50%
+ // of the cases generate a vector select.
+ if (Val0->getType()->isVectorTy() && (getRandom() % 1)) {
+ unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements();
+ CondTy = VectorType::get(CondTy, NumElem);
+ }
- Value *Cond = getRandomValue(CondTy);
- Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator());
- return PT->push_back(V);
+ Value *Cond = getRandomValue(CondTy);
+ Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator());
+ return PT->push_back(V);
}
};
-
struct CmpModifier: public Modifier {
- CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
- void Act() override {
+ CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R)
+ : Modifier(BB, PT, R) {}
+ void Act() override {
Value *Val0 = getRandomVal();
Value *Val1 = getRandomValue(Val0->getType());
}
}
-}
+} // end namespace llvm
int main(int argc, char **argv) {
using namespace llvm;
cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n");
llvm_shutdown_obj Y;
- auto M = make_unique<Module>("/tmp/autogen.bc", Context);
+ auto M = llvm::make_unique<Module>("/tmp/autogen.bc", Context);
Function *F = GenEmptyFunction(M.get());
// Pick an initial seed value
/// \brief Utilities to print analysis info for various kinds of passes.
///
//===----------------------------------------------------------------------===//
+
#include "PassPrinters.h"
+#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionPass.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
+#include "llvm/Support/raw_ostream.h"
#include <string>
using namespace llvm;
};
char BasicBlockPassPrinter::ID = 0;
-}
+
+} // end anonymous namespace
FunctionPass *llvm::createFunctionPassPrinter(const PassInfo *PI,
raw_ostream &OS, bool Quiet) {
-//===- PassPrinters.h - Utilities to print analysis info for passes -------===//
+//=- PassPrinters.h - Utilities to print analysis info for passes -*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
/// \brief Utilities to print analysis info for various kinds of passes.
///
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_TOOLS_OPT_PASSPRINTERS_H
#define LLVM_TOOLS_OPT_PASSPRINTERS_H
class ModulePass;
class LoopPass;
class PassInfo;
-class RegionPass;
class raw_ostream;
+class RegionPass;
FunctionPass *createFunctionPassPrinter(const PassInfo *PI, raw_ostream &out,
bool Quiet);
BasicBlockPass *createBasicBlockPassPrinter(const PassInfo *PI,
raw_ostream &out, bool Quiet);
-}
+
+} // end namespace llvm
#endif // LLVM_TOOLS_OPT_PASSPRINTERS_H