Skip to content

Commit

Permalink
Merge from 'sycl' to 'sycl-web'
Browse files Browse the repository at this point in the history
  • Loading branch information
iclsrc committed Feb 27, 2020
2 parents 7fa4ab4 + 6c41afe commit b524502
Show file tree
Hide file tree
Showing 20 changed files with 584 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gh_pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
repository: intel/llvm-docs
path: docs
- name: Install deps
run: sudo apt-get install -y doxygen graphviz ssh
run: sudo apt-get install -y doxygen graphviz ssh ninja-build
- name: Build Docs
run: |
mkdir -p $GITHUB_WORKSPACE/build
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,15 @@ def SYCLFPGAPipe : TypeAttr {
let Documentation = [SYCLFPGAPipeDocs];
}

def SYCLIntelPipeIO : Attr {
let Spellings = [GNU<"io_pipe_id">];
let Args = [ExprArgument<"ID">];
let LangOpts = [SYCLIsDevice, SYCLIsHost];
let Subjects = SubjectList<[Var]>;
let Documentation = [SYCLIntelPipeIOAttrDocs];
let PragmaAttributeSupport = 0;
}

// Variadic integral arguments.
def IntelFPGABankBits : Attr {
let Spellings = [CXX11<"intelfpga", "bank_bits">];
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -2033,6 +2033,20 @@ write only. Expected to be used only in SYCL headers.
}];
}

def SYCLIntelPipeIOAttrDocs : Documentation {
let Category = DocCatVariable;
let Heading = "IO pipe ID";
let Content = [{
Add I/O attribute to SYCL pipe declaration to declare a special I/O pipe to
interface with input or output features of an FPGA. These features might include
network interfaces, PCIe, cameras, or other data capture or processing devices
or protocols.

The io_pipe_id(id) attribute specifies the I/O feature of an accelerator board
with which a pipe interfaces. The id argument is the name of the I/O interface.
}];
}

def SYCLIntelFPGAIVDepAttrDocs : Documentation {
let Category = DocCatVariable;
let Heading = "ivdep";
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -9710,6 +9710,10 @@ class Sema final {
void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *Min, Expr *Max);

/// addSYCLIntelPipeIOAttr - Adds a pipe I/O attribute to a particular
/// declaration.
void addSYCLIntelPipeIOAttr(Decl *D, const AttributeCommonInfo &CI, Expr *ID);

bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);

//===--------------------------------------------------------------------===//
Expand Down
33 changes: 33 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3470,6 +3470,32 @@ bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
return true;
}

static void maybeEmitPipeStorageMetadata(const VarDecl *D,
llvm::GlobalVariable *GV,
CodeGenModule &CGM) {
// TODO: Applicable only on pipe storages. Currently they are defined
// as structures inside of SYCL headers. Add a check for pipe_storage_t
// when it ready.
QualType PipeTy = D->getType();
if (!PipeTy->isStructureType())
return;

if (auto *IOAttr = D->getAttr<SYCLIntelPipeIOAttr>()) {
llvm::APSInt ID(32);
llvm::LLVMContext &Context = CGM.getLLVMContext();
bool IsValid =
IOAttr->getID()->isIntegerConstantExpr(ID, D->getASTContext());
assert(IsValid && "Not an integer constant expression");
(void)IsValid;

llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::Type::getInt32Ty(Context), ID.getSExtValue()))};
GV->setMetadata(IOAttr->getSpelling(),
llvm::MDNode::get(Context, AttrMDArgs));
}
}

/// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
/// create and return an llvm GlobalVariable with the specified type. If there
/// is something in the module with the specified name, return it potentially
Expand Down Expand Up @@ -3659,6 +3685,10 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
: (LangOpts.OpenCL ? LangAS::opencl_global : LangAS::Default);
assert(getContext().getTargetAddressSpace(ExpectedAS) ==
Ty->getPointerAddressSpace());

if (LangOpts.SYCLIsDevice)
maybeEmitPipeStorageMetadata(D, GV, *this);

if (AddrSpace != ExpectedAS)
return getTargetCodeGenInfo().performAddrSpaceCast(*this, GV, AddrSpace,
ExpectedAS, Ty);
Expand Down Expand Up @@ -4310,6 +4340,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
if (CGDebugInfo *DI = getModuleDebugInfo())
if (getCodeGenOpts().hasReducedDebugInfo())
DI->EmitGlobalVariable(GV, D);

if (LangOpts.SYCLIsDevice)
maybeEmitPipeStorageMetadata(D, GV, *this);
}

void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {
Expand Down
44 changes: 44 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5516,6 +5516,47 @@ static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
PatchableFunctionEntryAttr(S.Context, AL, Count, Offset));
}

void Sema::addSYCLIntelPipeIOAttr(Decl *D, const AttributeCommonInfo &Attr,
Expr *E) {
VarDecl *VD = cast<VarDecl>(D);
QualType Ty = VD->getType();
// TODO: Applicable only on pipe storages. Currently they are defined
// as structures inside of SYCL headers. Add a check for pipe_storage_t
// when it is ready.
if (!Ty->isStructureType()) {
Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type_str)
<< Attr.getAttrName() << "SYCL pipe storage declaration";
return;
}

if (!E->isInstantiationDependent()) {
llvm::APSInt ArgVal(32);
if (!E->isIntegerConstantExpr(ArgVal, getASTContext())) {
Diag(E->getExprLoc(), diag::err_attribute_argument_type)
<< Attr.getAttrName() << AANT_ArgumentIntegerConstant
<< E->getSourceRange();
return;
}
int32_t ArgInt = ArgVal.getSExtValue();
if (ArgInt < 0) {
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
<< Attr.getAttrName() << /*non-negative*/ 1;
return;
}
}

D->addAttr(::new (Context) SYCLIntelPipeIOAttr(Context, Attr, E));
}

static void handleSYCLIntelPipeIOAttr(Sema &S, Decl *D,
const ParsedAttr &Attr) {
if (D->isInvalidDecl())
return;

Expr *E = Attr.getArgAsExpr(0);
S.addSYCLIntelPipeIOAttr(D, Attr, E);
}

static bool ArmMveAliasValid(unsigned BuiltinID, StringRef AliasName) {
if (AliasName.startswith("__arm_"))
AliasName = AliasName.substr(6);
Expand Down Expand Up @@ -8040,6 +8081,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_IntelFPGABankBits:
handleIntelFPGABankBitsAttr(S, D, AL);
break;
case ParsedAttr::AT_SYCLIntelPipeIO:
handleSYCLIntelPipeIOAttr(S, D, AL);
break;

case ParsedAttr::AT_AnyX86NoCallerSavedRegisters:
handleSimpleAttribute<AnyX86NoCallerSavedRegistersAttr>(S, D, AL);
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,17 @@ static void instantiateIntelFPGABankBitsAttr(
S.AddIntelFPGABankBitsAttr(New, *Attr, Args.data(), Args.size());
}

static void instantiateSYCLIntelPipeIOAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const SYCLIntelPipeIOAttr *Attr, Decl *New) {
// The ID expression is a constant expression.
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult Result = S.SubstExpr(Attr->getID(), TemplateArgs);
if (!Result.isInvalid())
S.addSYCLIntelPipeIOAttr(New, *Attr, Result.getAs<Expr>());
}

void Sema::InstantiateAttrsForDecl(
const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
Decl *New, LateInstantiatedAttrVec *LateAttrs,
Expand Down Expand Up @@ -686,6 +697,10 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
instantiateIntelFPGABankBitsAttr(*this, TemplateArgs, IntelFPGABankBits,
New);
}
if (const auto *SYCLIntelPipeIO = dyn_cast<SYCLIntelPipeIOAttr>(TmplAttr)) {
instantiateSYCLIntelPipeIOAttr(*this, TemplateArgs, SYCLIntelPipeIO, New);
continue;
}

// Existing DLL attribute on the instantiation takes precedence.
if (TmplAttr->getKind() == attr::DLLExport ||
Expand Down
40 changes: 39 additions & 1 deletion clang/test/CodeGenSYCL/fpga_pipes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,39 @@ RPipeTy RPipeCreator();
template <typename PipeTy>
void foo(PipeTy Pipe) {}

struct PipeStorageTy {
int Size;
};

// CHECK: @{{.*}}Storage = {{.*}} !io_pipe_id ![[ID0:[0-9]+]]
constexpr PipeStorageTy
Storage __attribute__((io_pipe_id(1))) = {1};

// CHECK: @{{.*}}TempStorage{{.*}} = {{.*}} !io_pipe_id ![[ID1:[0-9]+]]
template <int N>
constexpr PipeStorageTy
TempStorage __attribute__((io_pipe_id(N))) = {2};

void boo(PipeStorageTy PipeStorage);

template <int ID>
struct ethernet_pipe {
static constexpr int id = ID;
};

// CHECK: @{{.*}}PipeStorage{{.*}} = {{.*}} !io_pipe_id ![[ID2:[0-9]+]]
template <typename name>
class pipe {
public:
static void read() {
boo(PipeStorage);
}

private:
static constexpr PipeStorageTy
PipeStorage __attribute__((io_pipe_id(name::id))) = {3};
};

template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
kernelFunc();
Expand All @@ -24,7 +57,12 @@ int main() {
RPipeTy rpipe = RPipeCreator();
foo<WPipeTy>(wpipe);
foo<RPipeTy>(rpipe);
boo(Storage);
boo(TempStorage<2>);
pipe<ethernet_pipe<42>>::read();
});
return 0;
}

// CHECK: ![[ID0]] = !{i32 1}
// CHECK: ![[ID1]] = !{i32 2}
// CHECK: ![[ID2]] = !{i32 42}
32 changes: 32 additions & 0 deletions clang/test/SemaSYCL/fpga_pipes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,35 @@ using type4 = __attribute__((pipe(0))) const int;

// expected-error@+1{{'pipe' attribute takes one argument}}
using type5 = __attribute__((pipe)) const int;

struct pipe_storage {};

// no error expected
const pipe_storage Storage1 __attribute__((io_pipe_id(1)));

// expected-error@+1{{'io_pipe_id' attribute requires a non-negative integral compile time constant expression}}
const pipe_storage Storage2 __attribute__((io_pipe_id(-11)));

// expected-error@+1{{'io_pipe_id' attribute requires an integer constant}}
const pipe_storage Storage3 __attribute__((io_pipe_id("abc")));

// expected-error@+1{{'io_pipe_id' attribute only applies to SYCL pipe storage declaration}}
int Storage4 __attribute__((io_pipe_id(5)));

// expected-error@+2{{'io_pipe_id' attribute requires a non-negative integral compile time constant expression}}
template <int N>
pipe_storage Storage5 __attribute__((io_pipe_id(N)));

template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
kernelFunc();
}

void foo(pipe_storage PS) {}

int main() {
// no error expected
foo(Storage5<2>);
// expected-note@+1{{in instantiation of variable template specialization 'Storage5' requested here}}
foo(Storage5<-1>);
}
12 changes: 6 additions & 6 deletions sycl/doc/doxygen.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,15 @@ SHORT_NAMES = NO
# description.)
# The default value is: NO.

JAVADOC_AUTOBRIEF = NO
JAVADOC_AUTOBRIEF = YES

# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
# requiring an explicit \brief command for a brief description.)
# The default value is: NO.

QT_AUTOBRIEF = NO
QT_AUTOBRIEF = YES

# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
Expand Down Expand Up @@ -2061,15 +2061,15 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

MACRO_EXPANSION = NO
MACRO_EXPANSION = YES

# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
# EXPAND_AS_DEFINED tags.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

EXPAND_ONLY_PREDEF = NO
EXPAND_ONLY_PREDEF = YES

# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
Expand Down Expand Up @@ -2101,7 +2101,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

PREDEFINED =
PREDEFINED = "__SYCL_INLINE_NAMESPACE(X)=namespace X"

# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
Expand Down Expand Up @@ -2390,7 +2390,7 @@ DOT_IMAGE_FORMAT = @DOT_IMAGE_FORMAT@
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.

INTERACTIVE_SVG = NO
INTERACTIVE_SVG = YES

# The DOT_PATH tag can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
Expand Down
Loading

0 comments on commit b524502

Please sign in to comment.