Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix multitarget builds on Darwin #245

Merged
merged 7 commits into from
Jun 10, 2024
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3426,6 +3426,8 @@ void DarwinClang::AddOpenCilkABIBitcode(const ArgList &Args,
: "libopencilk-abi");
BitcodeFilename += "_";
BitcodeFilename += getOSLibraryNameSuffix();
BitcodeFilename += "-";
BitcodeFilename += getMachOArchName(Args);
BitcodeFilename += ".bc";

for (auto RuntimePath : getOpenCilkRuntimePaths(Args)) {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
// converted to a prvalue.
if (!E->isGLValue()) return E;

QualType T = E->getType();
QualType T = E->getType().stripHyperobject();
assert(!T.isNull() && "r-value conversion on typeless expression?");

// lvalue-to-rvalue conversion cannot be applied to function or array types.
Expand Down Expand Up @@ -687,7 +687,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
CheckForNullPointerDereference(*this, E);

E = BuildHyperobjectLookup(E);
T = E->getType();
assert(T == E->getType() && "Unexpected Type from hyperobject lookup.");

if (const ObjCIsaExpr *OISA = dyn_cast<ObjCIsaExpr>(E->IgnoreParenCasts())) {
NamedDecl *ObjectGetClass = LookupSingleName(TUScope,
Expand Down
15 changes: 15 additions & 0 deletions clang/test/Cilk/hyper-type-delete.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Check that calling delete on a hyperobject produces a useful error message.
//
// RUN: %clang_cc1 %s -xc++ -fopencilk -verify -fsyntax-only
struct S {
int x, y;
};
void identity(void *v);
void reduce(void *l, void *r);
using S_r = S _Hyperobject(identity, reduce);

class Foo {
S_r r; // expected-warning{{reducer callbacks not implemented for structure members}}
public:
~Foo() { delete r; }; // expected-error{{cannot delete expression of type 'S_r' (aka 'S _Hyperobject(identity, reduce)')}}
};
6 changes: 5 additions & 1 deletion llvm/include/llvm/Analysis/TapirTaskInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,11 @@ class Task {
/// Returns true if this task encloses basic block BB simply, that is, without
/// checking any shared EH exits of this task.
bool simplyEncloses(const BasicBlock *BB) const {
return DomTree.dominates(getEntry(), BB);
// DomTree.dominates(getEntry(), BB) will return true if BB is not reachable
// and getEntry() is reachable. This method should return that BB is not
// simply enclosed in that case.
return DomTree.isReachableFromEntry(BB) &&
DomTree.dominates(getEntry(), BB);
}

/// Return true if specified task encloses basic block BB.
Expand Down
9 changes: 6 additions & 3 deletions llvm/include/llvm/Transforms/Tapir/LoweringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#define LOWERING_UTILS_H_

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Instructions.h"
Expand Down Expand Up @@ -432,7 +431,10 @@ class LoopOutlineProcessor {
/// a common post-processing step for outlined helper functions.
void addSyncToOutlineReturns(TapirLoopInfo &TL, TaskOutlineInfo &Out,
ValueToValueMapTy &VMap);

/// Enclose the task of the Tapir loop in a taskframe, if the Tapir loop
/// contains nested spawns.
void maybeEncloseInTaskFrame(TapirLoopInfo &TL, TaskOutlineInfo &Out,
ValueToValueMapTy &VMap);
/// Move Cilksan instrumentation out of cloned loop.
void moveCilksanInstrumentation(TapirLoopInfo &TL, TaskOutlineInfo &Out,
ValueToValueMapTy &VMap);
Expand Down Expand Up @@ -503,6 +505,7 @@ void getTaskBlocks(Task *T, std::vector<BasicBlock *> &TaskBlocks,
SmallPtrSetImpl<BasicBlock *> &ReattachBlocks,
SmallPtrSetImpl<BasicBlock *> &TaskResumeBlocks,
SmallPtrSetImpl<BasicBlock *> &SharedEHEntries,
SmallPtrSetImpl<BasicBlock *> &UnreachableExits,
const DominatorTree *DT);

/// Outlines the content of task \p T in function \p F into a new helper
Expand Down Expand Up @@ -560,6 +563,6 @@ Instruction *replaceLoopWithCallToOutline(
TapirLoopInfo *TL, TaskOutlineInfo &Out,
SmallVectorImpl<Value *> &OutlineInputs);

} // end namepsace llvm
} // namespace llvm

#endif
66 changes: 29 additions & 37 deletions llvm/lib/Analysis/TapirTaskInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@
#include "llvm/Analysis/TapirTaskInfo.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/IteratedDominanceFrontier.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRPrintingPasses.h"
Expand All @@ -34,7 +32,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>

using namespace llvm;

Expand Down Expand Up @@ -214,11 +211,9 @@ bool Spindle::succInSameTask(const Spindle *Succ) const {
// properly contained in ParentTask, return true.
if (getParentTask()->contains(Succ))
return true;
else {
// Otherwise, check if Succ is a shared EH spindle tracked by the parent of
// ParentTask.
return getParentTask()->isSharedEHExit(Succ);
}
// Otherwise, check if Succ is a shared EH spindle tracked by the parent of
// ParentTask.
return getParentTask()->isSharedEHExit(Succ);
}

/// Return true if the successor spindle Succ is in a subtask of the task
Expand Down Expand Up @@ -284,14 +279,14 @@ void Task::getSharedEHExits(SmallVectorImpl<Spindle *> &SpindleVec) const {
// themselves detach. It's not clear how this case could arise in practice,
// however.
SmallPtrSet<const Task *, 4> Ancestors;
bool tracksSharedEHSpindles = false;
bool TracksSharedEHSpindles = false;
const Task *Parent = this;
do {
Parent = Parent->getParentTask();
Ancestors.insert(Parent);
tracksSharedEHSpindles |= Parent->tracksSharedEHSpindles();
TracksSharedEHSpindles |= Parent->tracksSharedEHSpindles();
} while (!Parent->isRootTask());
if (!tracksSharedEHSpindles) return;
if (!TracksSharedEHSpindles) return;

// Scan the successors of the spindles in this task to find shared EH exits.
SmallVector<Spindle *, 4> WorkList;
Expand Down Expand Up @@ -327,14 +322,14 @@ bool Task::isSharedEHExit(const Spindle *SharedEH) const {
// themselves detach. It's not clear how this case could arise in practice,
// however.
SmallPtrSet<const Task *, 4> Ancestors;
bool tracksSharedEHSpindles = false;
bool TracksSharedEHSpindles = false;
const Task *Parent = this;
do {
Parent = Parent->getParentTask();
Ancestors.insert(Parent);
tracksSharedEHSpindles |= Parent->tracksSharedEHSpindles();
TracksSharedEHSpindles |= Parent->tracksSharedEHSpindles();
} while (!Parent->isRootTask());
if (!tracksSharedEHSpindles) return false;
if (!TracksSharedEHSpindles) return false;

Task *SharedEHParent = SharedEH->getParentTask();
if (!Ancestors.contains(SharedEHParent))
Expand Down Expand Up @@ -375,9 +370,8 @@ bool Task::isSharedEHExit(const Spindle *SharedEH) const {

// Add the unassociated spindles to the task T in order of a DFS CFG traversal
// starting at the entry block of T.
static void
AssociateWithTask(TaskInfo *TI, Task *T,
SmallPtrSetImpl<Spindle *> &UnassocSpindles) {
static void associateWithTask(TaskInfo *TI, Task *T,
SmallPtrSetImpl<Spindle *> &UnassocSpindles) {
SmallVector<Spindle *, 8> WorkList;
SmallPtrSet<Spindle *, 8> Visited;
// Add the successor spindles of the entry block of T to the worklist.
Expand Down Expand Up @@ -423,9 +417,8 @@ AssociateWithTask(TaskInfo *TI, Task *T,

// Add the unassociated blocks to the spindle S in order of a DFS CFG traversal
// starting at the entry block of S.
static void
AssociateWithSpindle(TaskInfo *TI, Spindle *S,
SmallPtrSetImpl<BasicBlock *> &UnassocBlocks) {
static void associateWithSpindle(TaskInfo *TI, Spindle *S,
SmallPtrSetImpl<BasicBlock *> &UnassocBlocks) {
SmallVector<BasicBlock *, 32> WorkList;
SmallPtrSet<BasicBlock *, 32> Visited;
// Add the successor blocks of the entry of S to the worklist.
Expand Down Expand Up @@ -482,7 +475,7 @@ static void computeSpindleEdges(TaskInfo *TI) {

// Search the PHI nodes in BB for a user of Val. Return Val if no PHI node in
// BB uses Val.
static Value *FindUserAmongPHIs(Value *Val, BasicBlock *BB) {
static Value *findUserAmongPHIs(Value *Val, BasicBlock *BB) {
for (PHINode &PN : BB->phis()) {
if (Val->getType() != PN.getType())
continue;
Expand Down Expand Up @@ -526,7 +519,7 @@ static void recordContinuationSpindles(TaskInfo *TI) {
"Unwind destination of detach has many successors, but belongs to "
"the same spindle as the detach.");
Unwind = Unwind->getUniqueSuccessor();
LPadVal = FindUserAmongPHIs(LPadVal, Unwind);
LPadVal = findUserAmongPHIs(LPadVal, Unwind);
}
// Set the exceptional continuation spindle for this task.
Spindle *UnwindSpindle = TI->getSpindleFor(Unwind);
Expand Down Expand Up @@ -777,7 +770,7 @@ void TaskInfo::analyze(Function &F, DominatorTree &DomTree) {
SmallVector<Spindle *, 8> FoundSpindles;
SmallVector<Spindle *, 8> FoundTFCreates;
SmallVector<Task *, 4> UnassocTasks;
for (auto DomNode : post_order(DomTree.getRootNode())) {
for (auto *DomNode : post_order(DomTree.getRootNode())) {
BasicBlock *BB = DomNode->getBlock();
// If a basic block is not a spindle entry, mark it found and continue.
if (!getSpindleFor(BB)) {
Expand Down Expand Up @@ -810,7 +803,7 @@ void TaskInfo::analyze(Function &F, DominatorTree &DomTree) {

// Associate the unassociated blocks with spindle S.
if (!UnassocBlocks.empty())
AssociateWithSpindle(this, S, UnassocBlocks);
associateWithSpindle(this, S, UnassocBlocks);
}

// Mark taskframe.create spindles found.
Expand Down Expand Up @@ -851,7 +844,7 @@ void TaskInfo::analyze(Function &F, DominatorTree &DomTree) {
}
// Associate the unassociated spindles with task T.
if (!UnassocSpindles.empty())
AssociateWithTask(this, T, UnassocSpindles);
associateWithTask(this, T, UnassocSpindles);
}

// If the last task is dominated by this task, add the unassociated tasks as
Expand Down Expand Up @@ -964,14 +957,13 @@ void TaskInfo::findTaskFrameTreeHelper(
// Recur into the new taskframe.
findTaskFrameTreeHelper(SubTF, WorkList, SubTFVisited);
continue;
} else {
LLVM_DEBUG({
if (!TFSpindle->SubTaskFrames.count(SuccEdge.first))
dbgs() << "Search encountered subtask@"
<< SubT->getEntry()->getName() << " with taskframe "
<< "before that subtask's taskframe.create.";
});
}
LLVM_DEBUG({
if (!TFSpindle->SubTaskFrames.count(SuccEdge.first))
dbgs() << "Search encountered subtask@"
<< SubT->getEntry()->getName() << " with taskframe "
<< "before that subtask's taskframe.create.";
});
}
}

Expand Down Expand Up @@ -1090,7 +1082,7 @@ void TaskInfo::findTaskFrameTree() {
/// These are blocks which lead to uses. Knowing this allows us to avoid
/// inserting PHI nodes into blocks which don't lead to uses (thus, the inserted
/// phi nodes would be dead).
static void ComputeLiveInBlocks(
static void computeLiveInBlocks(
const AllocaInst *AI,
const SmallVectorImpl<BasicBlock *> &UsingBlocks,
const SmallPtrSetImpl<BasicBlock *> &DefBlocks,
Expand Down Expand Up @@ -1223,7 +1215,7 @@ bool TaskInfo::isAllocaParallelPromotable(const AllocaInst *AIP) const {
// Determine which blocks the value is live in. These are blocks which lead
// to uses.
SmallPtrSet<BasicBlock *, 32> LiveInBlocks;
ComputeLiveInBlocks(AI, UsingBlocks, DefBlocks, LiveInBlocks);
computeLiveInBlocks(AI, UsingBlocks, DefBlocks, LiveInBlocks);
// Filter out live-in blocks that are not dominated by the alloca.
if (AI->getParent() != DomTree.getRoot()) {
SmallVector<BasicBlock *, 32> LiveInToRemove;
Expand Down Expand Up @@ -1289,9 +1281,9 @@ bool IsSyncedState::evaluate(const Spindle *S, unsigned EvalNum) {
if (!EvalNum && !SyncedState.count(Pred)) {
SyncedState[S] = setIncomplete(SyncedState[S]);
continue;
} else
assert(SyncedState.count(Pred) &&
"All predecessors should have synced states after first eval.");
}
assert(SyncedState.count(Pred) &&
"All predecessors should have synced states after first eval.");

// If we find an unsynced predecessor that is not terminated by a sync
// instruction, then we must be unsynced.
Expand Down
Loading
Loading