forked from OSchip/llvm-project
[PM] port Rewrite Statepoints For GC to the new pass manager.
Summary: The port is nearly straightforward. The only complication is related to the analyses handling, since one of the analyses used in this module pass is domtree, which is a function analysis. That requires asking for the results of each function and disallows a single interface for run-on-module pass action. Decided to copy-paste the main body of this pass. Most of its code is requesting analyses anyway, so not that much of a copy-paste. The rest of the code movement is to transform all the implementation helper functions like stripNonValidData into non-member statics. Extended all the related LLVM tests with new-pass-manager use. No failures. Reviewers: sanjoy, anna, reames Reviewed By: anna Subscribers: skatkov, llvm-commits Differential Revision: https://reviews.llvm.org/D41162 llvm-svn: 320796
This commit is contained in:
parent
9fcc4727ac
commit
4b86d79048
|
@ -321,7 +321,7 @@ void initializeRegisterCoalescerPass(PassRegistry&);
|
|||
void initializeRenameIndependentSubregsPass(PassRegistry&);
|
||||
void initializeResetMachineFunctionPass(PassRegistry&);
|
||||
void initializeReversePostOrderFunctionAttrsLegacyPassPass(PassRegistry&);
|
||||
void initializeRewriteStatepointsForGCPass(PassRegistry&);
|
||||
void initializeRewriteStatepointsForGCLegacyPassPass(PassRegistry &);
|
||||
void initializeRewriteSymbolsLegacyPassPass(PassRegistry&);
|
||||
void initializeSafepointIRVerifierPass(PassRegistry&);
|
||||
void initializeSCCPLegacyPassPass(PassRegistry&);
|
||||
|
|
|
@ -521,7 +521,7 @@ FunctionPass *createPlaceSafepointsPass();
|
|||
// RewriteStatepointsForGC - Rewrite any gc.statepoints which do not yet have
|
||||
// explicit relocations to include explicit relocations.
|
||||
//
|
||||
ModulePass *createRewriteStatepointsForGCPass();
|
||||
ModulePass *createRewriteStatepointsForGCLegacyPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
//===- RewriteStatepointsForGC.h - ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides interface to "Rewrite Statepoints for GC" pass.
|
||||
//
|
||||
// This passe rewrites call/invoke instructions so as to make potential
|
||||
// relocations performed by the garbage collector explicit in the IR.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
|
||||
#define LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class DominatorTree;
|
||||
class Function;
|
||||
class Module;
|
||||
class TargetTransformInfo;
|
||||
class TargetLibraryInfo;
|
||||
|
||||
struct RewriteStatepointsForGC : public PassInfoMixin<RewriteStatepointsForGC> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
bool runOnFunction(Function &F, DominatorTree &, TargetTransformInfo &,
|
||||
const TargetLibraryInfo &);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
|
|
@ -126,6 +126,7 @@
|
|||
#include "llvm/Transforms/Scalar/NewGVN.h"
|
||||
#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
|
||||
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||
#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
|
||||
#include "llvm/Transforms/Scalar/SCCP.h"
|
||||
#include "llvm/Transforms/Scalar/SROA.h"
|
||||
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
|
||||
|
|
|
@ -68,6 +68,7 @@ MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
|
|||
MODULE_PASS("print", PrintModulePass(dbgs()))
|
||||
MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
|
||||
MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs()))
|
||||
MODULE_PASS("rewrite-statepoints-for-gc", RewriteStatepointsForGC())
|
||||
MODULE_PASS("rewrite-symbols", RewriteSymbolPass())
|
||||
MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass())
|
||||
MODULE_PASS("sample-profile", SampleProfileLoaderPass())
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
|
@ -108,30 +110,96 @@ static cl::opt<bool>
|
|||
AllowStatepointWithNoDeoptInfo("rs4gc-allow-statepoint-with-no-deopt-info",
|
||||
cl::Hidden, cl::init(true));
|
||||
|
||||
/// The IR fed into RewriteStatepointsForGC may have had attributes and
|
||||
/// metadata implying dereferenceability that are no longer valid/correct after
|
||||
/// RewriteStatepointsForGC has run. This is because semantically, after
|
||||
/// RewriteStatepointsForGC runs, all calls to gc.statepoint "free" the entire
|
||||
/// heap. stripNonValidData (conservatively) restores
|
||||
/// correctness by erasing all attributes in the module that externally imply
|
||||
/// dereferenceability. Similar reasoning also applies to the noalias
|
||||
/// attributes and metadata. gc.statepoint can touch the entire heap including
|
||||
/// noalias objects.
|
||||
/// Apart from attributes and metadata, we also remove instructions that imply
|
||||
/// constant physical memory: llvm.invariant.start.
|
||||
static void stripNonValidData(Module &M);
|
||||
|
||||
static bool shouldRewriteStatepointsIn(Function &F);
|
||||
|
||||
PreservedAnalyses RewriteStatepointsForGC::run(Module &M,
|
||||
ModuleAnalysisManager &AM) {
|
||||
bool Changed = false;
|
||||
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
for (Function &F : M) {
|
||||
// Nothing to do for declarations.
|
||||
if (F.isDeclaration() || F.empty())
|
||||
continue;
|
||||
|
||||
// Policy choice says not to rewrite - the most common reason is that we're
|
||||
// compiling code without a GCStrategy.
|
||||
if (!shouldRewriteStatepointsIn(F))
|
||||
continue;
|
||||
|
||||
auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
|
||||
auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
|
||||
Changed |= runOnFunction(F, DT, TTI, TLI);
|
||||
}
|
||||
if (!Changed)
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
// stripNonValidData asserts that shouldRewriteStatepointsIn
|
||||
// returns true for at least one function in the module. Since at least
|
||||
// one function changed, we know that the precondition is satisfied.
|
||||
stripNonValidData(M);
|
||||
|
||||
PreservedAnalyses PA;
|
||||
PA.preserve<TargetIRAnalysis>();
|
||||
PA.preserve<TargetLibraryAnalysis>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct RewriteStatepointsForGC : public ModulePass {
|
||||
class RewriteStatepointsForGCLegacyPass : public ModulePass {
|
||||
RewriteStatepointsForGC Impl;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
RewriteStatepointsForGC() : ModulePass(ID) {
|
||||
initializeRewriteStatepointsForGCPass(*PassRegistry::getPassRegistry());
|
||||
RewriteStatepointsForGCLegacyPass() : ModulePass(ID), Impl() {
|
||||
initializeRewriteStatepointsForGCLegacyPassPass(
|
||||
*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F);
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
bool Changed = false;
|
||||
for (Function &F : M)
|
||||
Changed |= runOnFunction(F);
|
||||
const TargetLibraryInfo &TLI =
|
||||
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
for (Function &F : M) {
|
||||
// Nothing to do for declarations.
|
||||
if (F.isDeclaration() || F.empty())
|
||||
continue;
|
||||
|
||||
if (Changed) {
|
||||
// stripNonValidData asserts that shouldRewriteStatepointsIn
|
||||
// returns true for at least one function in the module. Since at least
|
||||
// one function changed, we know that the precondition is satisfied.
|
||||
stripNonValidData(M);
|
||||
// Policy choice says not to rewrite - the most common reason is that
|
||||
// we're compiling code without a GCStrategy.
|
||||
if (!shouldRewriteStatepointsIn(F))
|
||||
continue;
|
||||
|
||||
TargetTransformInfo &TTI =
|
||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
|
||||
|
||||
Changed |= Impl.runOnFunction(F, DT, TTI, TLI);
|
||||
}
|
||||
|
||||
return Changed;
|
||||
if (!Changed)
|
||||
return false;
|
||||
|
||||
// stripNonValidData asserts that shouldRewriteStatepointsIn
|
||||
// returns true for at least one function in the module. Since at least
|
||||
// one function changed, we know that the precondition is satisfied.
|
||||
stripNonValidData(M);
|
||||
return true;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
|
@ -141,43 +209,23 @@ struct RewriteStatepointsForGC : public ModulePass {
|
|||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
}
|
||||
|
||||
/// The IR fed into RewriteStatepointsForGC may have had attributes and
|
||||
/// metadata implying dereferenceability that are no longer valid/correct after
|
||||
/// RewriteStatepointsForGC has run. This is because semantically, after
|
||||
/// RewriteStatepointsForGC runs, all calls to gc.statepoint "free" the entire
|
||||
/// heap. stripNonValidData (conservatively) restores
|
||||
/// correctness by erasing all attributes in the module that externally imply
|
||||
/// dereferenceability. Similar reasoning also applies to the noalias
|
||||
/// attributes and metadata. gc.statepoint can touch the entire heap including
|
||||
/// noalias objects.
|
||||
/// Apart from attributes and metadata, we also remove instructions that imply
|
||||
/// constant physical memory: llvm.invariant.start.
|
||||
void stripNonValidData(Module &M);
|
||||
|
||||
// Helpers for stripNonValidData
|
||||
void stripNonValidDataFromBody(Function &F);
|
||||
void stripNonValidAttributesFromPrototype(Function &F);
|
||||
|
||||
// Certain metadata on instructions are invalid after running RS4GC.
|
||||
// Optimizations that run after RS4GC can incorrectly use this metadata to
|
||||
// optimize functions. We drop such metadata on the instruction.
|
||||
void stripInvalidMetadataFromInstruction(Instruction &I);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char RewriteStatepointsForGC::ID = 0;
|
||||
char RewriteStatepointsForGCLegacyPass::ID = 0;
|
||||
|
||||
ModulePass *llvm::createRewriteStatepointsForGCPass() {
|
||||
return new RewriteStatepointsForGC();
|
||||
ModulePass *llvm::createRewriteStatepointsForGCLegacyPass() {
|
||||
return new RewriteStatepointsForGCLegacyPass();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(RewriteStatepointsForGC, "rewrite-statepoints-for-gc",
|
||||
INITIALIZE_PASS_BEGIN(RewriteStatepointsForGCLegacyPass,
|
||||
"rewrite-statepoints-for-gc",
|
||||
"Make relocations explicit at statepoints", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(RewriteStatepointsForGC, "rewrite-statepoints-for-gc",
|
||||
INITIALIZE_PASS_END(RewriteStatepointsForGCLegacyPass,
|
||||
"rewrite-statepoints-for-gc",
|
||||
"Make relocations explicit at statepoints", false, false)
|
||||
|
||||
namespace {
|
||||
|
@ -2346,8 +2394,7 @@ static void RemoveNonValidAttrAtIndex(LLVMContext &Ctx, AttrHolder &AH,
|
|||
AH.setAttributes(AH.getAttributes().removeAttributes(Ctx, Index, R));
|
||||
}
|
||||
|
||||
void
|
||||
RewriteStatepointsForGC::stripNonValidAttributesFromPrototype(Function &F) {
|
||||
static void stripNonValidAttributesFromPrototype(Function &F) {
|
||||
LLVMContext &Ctx = F.getContext();
|
||||
|
||||
for (Argument &A : F.args())
|
||||
|
@ -2359,7 +2406,10 @@ RewriteStatepointsForGC::stripNonValidAttributesFromPrototype(Function &F) {
|
|||
RemoveNonValidAttrAtIndex(Ctx, F, AttributeList::ReturnIndex);
|
||||
}
|
||||
|
||||
void RewriteStatepointsForGC::stripInvalidMetadataFromInstruction(Instruction &I) {
|
||||
/// Certain metadata on instructions are invalid after running RS4GC.
|
||||
/// Optimizations that run after RS4GC can incorrectly use this metadata to
|
||||
/// optimize functions. We drop such metadata on the instruction.
|
||||
static void stripInvalidMetadataFromInstruction(Instruction &I) {
|
||||
if (!isa<LoadInst>(I) && !isa<StoreInst>(I))
|
||||
return;
|
||||
// These are the attributes that are still valid on loads and stores after
|
||||
|
@ -2387,7 +2437,7 @@ void RewriteStatepointsForGC::stripInvalidMetadataFromInstruction(Instruction &I
|
|||
I.dropUnknownNonDebugMetadata(ValidMetadataAfterRS4GC);
|
||||
}
|
||||
|
||||
void RewriteStatepointsForGC::stripNonValidDataFromBody(Function &F) {
|
||||
static void stripNonValidDataFromBody(Function &F) {
|
||||
if (F.empty())
|
||||
return;
|
||||
|
||||
|
@ -2462,7 +2512,7 @@ static bool shouldRewriteStatepointsIn(Function &F) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void RewriteStatepointsForGC::stripNonValidData(Module &M) {
|
||||
static void stripNonValidData(Module &M) {
|
||||
#ifndef NDEBUG
|
||||
assert(llvm::any_of(M, shouldRewriteStatepointsIn) && "precondition!");
|
||||
#endif
|
||||
|
@ -2474,21 +2524,12 @@ void RewriteStatepointsForGC::stripNonValidData(Module &M) {
|
|||
stripNonValidDataFromBody(F);
|
||||
}
|
||||
|
||||
bool RewriteStatepointsForGC::runOnFunction(Function &F) {
|
||||
// Nothing to do for declarations.
|
||||
if (F.isDeclaration() || F.empty())
|
||||
return false;
|
||||
|
||||
// Policy choice says not to rewrite - the most common reason is that we're
|
||||
// compiling code without a GCStrategy.
|
||||
if (!shouldRewriteStatepointsIn(F))
|
||||
return false;
|
||||
|
||||
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
|
||||
TargetTransformInfo &TTI =
|
||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
const TargetLibraryInfo &TLI =
|
||||
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
|
||||
TargetTransformInfo &TTI,
|
||||
const TargetLibraryInfo &TLI) {
|
||||
assert(!F.isDeclaration() && !F.empty() &&
|
||||
"need function body to rewrite statepoints in");
|
||||
assert(shouldRewriteStatepointsIn(F) && "mismatch in rewrite decision");
|
||||
|
||||
auto NeedsRewrite = [&TLI](Instruction &I) {
|
||||
if (ImmutableCallSite CS = ImmutableCallSite(&I))
|
||||
|
|
|
@ -81,7 +81,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
|
|||
initializePartiallyInlineLibCallsLegacyPassPass(Registry);
|
||||
initializeReassociateLegacyPassPass(Registry);
|
||||
initializeRegToMemPass(Registry);
|
||||
initializeRewriteStatepointsForGCPass(Registry);
|
||||
initializeRewriteStatepointsForGCLegacyPassPass(Registry);
|
||||
initializeSCCPLegacyPassPass(Registry);
|
||||
initializeIPSCCPLegacyPassPass(Registry);
|
||||
initializeSROALegacyPassPass(Registry);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %merged_value base %merged_value.base
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
|
||||
declare i1 @runtime_value() "gc-leaf-function"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %next base %base_obj
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %select base null
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %derived base null
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %merged_value base %base_obj
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %next.i64 base %base_obj
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %obj_to_consume base %obj_to_consume.base
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %merged_value base %merged_value.base
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %merged_value base %merged_value.base
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %merged_value base %merged_value.base
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %next_element_ptr base %array_obj
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: derived %next base %base_obj
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
|
||||
|
||||
; The rewriting needs to make %obj loop variant by inserting a phi
|
||||
; of the original value and it's relocation.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
|
||||
|
||||
define i64 addrspace(1)* @test(<2 x i64 addrspace(1)*> %vec, i32 %idx) gc "statepoint-example" {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
|
||||
declare void @g()
|
||||
declare i32 @h()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
; This is a collection of really basic tests for gc.statepoint rewriting.
|
||||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
|
||||
|
||||
; Trivial relocation over a single call
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
;; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
;; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
|
||||
;; This test is to verify that gc_result from a call statepoint
|
||||
;; can have preceding phis in its parent basic block. Unlike
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
|
||||
; A null test of a single value
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
|
||||
; constants don't get relocated.
|
||||
@G = addrspace(1) global i8 5
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.11.0"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.11.0"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; Check that the "deopt-lowering" function attribute gets transcoded into
|
||||
; flags on the resulting statepoint
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
|
||||
; CHECK: declare i8 addrspace(1)* @some_function_ret_deref()
|
||||
; CHECK: define i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* %a)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
|
||||
; This test checks that metadata that's invalid after RS4GC is dropped.
|
||||
; We can miscompile if optimizations scheduled after RS4GC uses the
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
|
||||
; This test is to verify gc.relocate can handle pointer to vector of
|
||||
; pointers (<2 x i32 addrspace(1)*> addrspace(1)* in this case).
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
|
||||
; RUN: opt < %s -S -passes=rewrite-statepoints-for-gc | FileCheck %s
|
||||
|
||||
declare i64 addrspace(1)* @some_call(i64 addrspace(1)*)
|
||||
declare i32 @personality_function()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
|
||||
; RUN: opt < %s -S -passes=rewrite-statepoints-for-gc | FileCheck %s
|
||||
|
||||
declare void @foo() "gc-leaf-function"
|
||||
declare void @bar()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
; This test verifies that calls to libcalls functions do not get converted to
|
||||
; statepoint calls.
|
||||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
|
||||
declare double @ldexp(double %x, i32 %n) nounwind readnone
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
; Test that we can correctly handle vectors of pointers in statepoint
|
||||
; rewriting.
|
||||
; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
|
||||
; A non-vector relocation for comparison
|
||||
define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
; A collection of liveness test cases to ensure we're reporting the
|
||||
; correct live values at statepoints
|
||||
; RUN: opt -rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S < %s | FileCheck %s
|
||||
|
||||
; Tests to make sure we consider %obj live in both the taken and untaken
|
||||
; predeccessor of merge.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
|
||||
declare void @f()
|
||||
declare i32 @personality_function()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
|
||||
; Test to make sure we destroy LCSSA's single entry phi nodes before
|
||||
; running liveness
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
;; RUN: opt -rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
|
||||
;; RUN: opt -passes=rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
|
||||
;; This test is to verify that RewriteStatepointsForGC correctly relocates values
|
||||
;; defined by invoke instruction results.
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
|
||||
|
||||
|
||||
declare void @foo()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
|
||||
|
||||
declare void @use_obj16(i16 addrspace(1)*) "gc-leaf-function"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
|
||||
|
||||
declare i8 addrspace(1)* @gc_call()
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; Ensure statepoints copy (valid) attributes from callsites.
|
||||
|
||||
declare void @f(i8 addrspace(1)* %obj)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
|
||||
; Ensure that the gc.statepoint calls / invokes we generate carry over
|
||||
; the right calling conventions.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
|
||||
; RUN: opt < %s -S -passes=rewrite-statepoints-for-gc | FileCheck %s
|
||||
|
||||
; Basic test to make sure that safepoints are placed
|
||||
; for CoreCLR GC
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
|
||||
|
||||
; Ensure that the gc.statepoint calls / invokes we generate have the
|
||||
; set of arguments we expect it to have.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
|
||||
|
||||
declare void @some_call(i64 addrspace(1)*)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
|
||||
;
|
||||
; A test to make sure that we can look through bitcasts of
|
||||
; vector types when a base pointer is contained in a vector.
|
||||
|
|
Loading…
Reference in New Issue