Skip to content

Commit

Permalink
[SYCL] ReFix edge detection.
Browse files Browse the repository at this point in the history
I thought it was fixed but couldn't get it working.
in sw_emu edge detection failed because of array partition metadata.
and in hw_emu and hw it failed because of pipeline metadata.
array partition metadata don't cause any issues in hw or hw_emu so there just disabled in sw_emu.
for pipeline metadata, what v++ generate and what the docs says it should generate don't match.
previously we generated what v++ generate, now we generate what the doc says we should and it fixes ths issue.
  • Loading branch information
Gauthier Harnisch committed Oct 7, 2020
1 parent 58e1336 commit daaca1b
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
16 changes: 15 additions & 1 deletion clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,22 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("SYCL_EXTERNAL", "__attribute__((sycl_device))");
// Defines a macro that switches on SPIR intrinsics in SYCL runtime, used
// by Xilinx FPGA devices for the moment
if (LangOpts.SYCLXOCCDevice)
if (LangOpts.SYCLXOCCDevice) {
Builder.defineMacro("__SYCL_SPIR_DEVICE__");
switch (TI.getTriple().getSubArch()) {
case llvm::Triple::FPGASubArch_sw_emu:
Builder.defineMacro("__SYCL_XILINX_SW_EMU_MODE__");
break;
case llvm::Triple::FPGASubArch_hw_emu:
Builder.defineMacro("__SYCL_XILINX_HW_EMU_MODE__");
break;
case llvm::Triple::FPGASubArch_hw:
Builder.defineMacro("__SYCL_XILINX_HW_MODE__");
break;
default:
break;
}
}

if (TI.getTriple().isNVPTX()) {
Builder.defineMacro("__SYCL_NVPTX__", "1");
Expand Down
8 changes: 5 additions & 3 deletions llvm/lib/SYCL/LowerSYCLMetaData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,10 @@ struct LSMDState {
ResultMD.push_back(MDNode::get(
Ctx, {MDString::get(Ctx, "llvm.loop.pipeline.enable"),
ConstantAsMetadata::get(
ConstantInt::get(Type::getInt32Ty(Ctx), 1)),
ConstantInt::get(Type::getInt32Ty(Ctx), -1)),
ConstantAsMetadata::get(
ConstantInt::getFalse(Type::getInt1Ty(Ctx))),
ConstantAsMetadata::get(
ConstantInt::get(Type::getInt8Ty(Ctx), -1))}));
}));
MDNode *MDN = MDNode::getDistinct(Ctx, ResultMD);
BB->getTerminator()->setMetadata(LLVMContext::MD_loop, MDN);
BB->getTerminator()
Expand Down Expand Up @@ -162,6 +161,9 @@ struct LowerSYCLMetaData : public ModulePass {
bool runOnModule(Module &M) override {
return LSMDState(M).run();
}
virtual StringRef getPassName() const override {
return "LowerSYCLMetaData";
}
};
}

Expand Down
36 changes: 35 additions & 1 deletion llvm/lib/SYCL/PrepareSYCLOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
#include <regex>
#include <string>

#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/SYCL/PrepareSYCLOpt.h"
#include "llvm/Support/Casting.h"

Expand All @@ -33,7 +35,7 @@ struct PrepareSYCLOpt : public ModulePass {
void turnNonKernelsIntoPrivate(Module &M) {
for (GlobalObject &G : M.global_objects()) {
if (auto *F = dyn_cast<Function>(&G))
if (F->getName().startswith("xSYCL"))
if (F->getName().startswith("xSYCL") || F->isIntrinsic())
continue;
if (G.isDeclaration())
continue;
Expand All @@ -47,6 +49,8 @@ struct PrepareSYCLOpt : public ModulePass {
assert(F.use_empty());
continue;
}
if (F.isIntrinsic())
continue;
F.setCallingConv(CallingConv::SPIR_FUNC);
for (Value* V : F.users()) {
if (auto* Call = dyn_cast<CallBase>(V))
Expand All @@ -55,9 +59,39 @@ struct PrepareSYCLOpt : public ModulePass {
}
}

void fixArrayPartition(Module& M) {
Function* Func = Intrinsic::getDeclaration(&M, Intrinsic::sideeffect);
for (Use& U : Func->uses()) {
auto* Usr = dyn_cast<CallBase>(U.getUser());
if (!Usr)
continue;
if (!Usr->getOperandBundle("xlx_array_partition"))
continue;
Use& Ptr = U.getUser()->getOperandUse(0);
Value* Obj = getUnderlyingObject(Ptr);
if (!isa<AllocaInst>(Obj))
return;
auto* Alloca = cast<AllocaInst>(Obj);
auto *Replacement =
new AllocaInst(Ptr->getType()->getPointerElementType(), 0,
ConstantInt::get(Type::getInt32Ty(M.getContext()), 1),
Align(128), "");
Replacement->insertAfter(Alloca);
Instruction* Cast = BitCastInst::Create(
Instruction::BitCast, Replacement, Alloca->getType());
Cast->insertAfter(Replacement);
Alloca->replaceAllUsesWith(Cast);
Value* Zero = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0);
Instruction* GEP = GetElementPtrInst::Create(nullptr, Replacement, {Zero});
GEP->insertAfter(Cast);
Ptr.set(GEP);
}
}

bool runOnModule(Module &M) override {
turnNonKernelsIntoPrivate(M);
setCallingConventions(M);
fixArrayPartition(M);
return true;
}
};
Expand Down
5 changes: 4 additions & 1 deletion sycl/include/CL/sycl/xilinx/fpga/partition_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ namespace partition {
/// This fuction is currently empty but the LowerSYCLMetaData Pass will fill
/// it with the required IR.
template<typename Ptr>
__SYCL_DEVICE_ANNOTATE("xilinx_partition_array") __attribute__((always_inline))
#if defined(__SYCL_XILINX_HW_EMU_MODE__) || defined(__SYCL_XILINX_HW_MODE__)
__SYCL_DEVICE_ANNOTATE("xilinx_partition_array")
#endif
__attribute__((always_inline))
inline void xilinx_partition_array(Ptr, int, int, int) {}

/** Represent a cyclic partition.
Expand Down

0 comments on commit daaca1b

Please sign in to comment.