使用clang-llvm编译器在CUDA中添加对类似于__shared__的内存类型的支持

时间:2016-02-20 06:05:50

标签: cuda clang llvm llvm-clang llvm-ir

我正在努力在CUDA中添加一个类似于__shared__的新内存类型,名为__noc__,需要使用clang-llvm进行编译。以下是从answer

获取引用来实现解析新内存类型的步骤

第1步:在clangs的Attr.td文件(clang / include / clang / Basic / Attr.td)中,添加了类似于shared关键字的noc关键字。

def CUDAShared : InheritableAttr {
  let Spellings = [GNU<"shared">];
  let Subjects = SubjectList<[Var]>;
  let LangOpts = [CUDA];
  let Documentation = [Undocumented];
}

def CUDANoc : InheritableAttr {
  let Spellings = [Keyword<"noc">];
  let Subjects = SubjectList<[Var]>;
  let LangOpts = [CUDA];
  let Documentation = [Undocumented];
}

第2步:与CUDASharedAttr类似,在clang / lib / Sema / SemaDeclAttr.cpp中添加了CUDANocAttr

  case AttributeList::AT_CUDAShared:
    handleSimpleAttribute<CUDASharedAttr>(S, D, Attr);
    break;
  case AttributeList::AT_CUDANoc:
    handleSimpleAttribute<CUDANocAttr>(S, D, Attr);
    printf("\n T1:SemaDeclAttr.cpp"); //testpoint 1 : for noc debugging
    break;

第3步:在SemaDecl.cpp文件中,添加了CUDANocAttr以强制noc为静态存储(类似于共享)

  if (getLangOpts().CUDA) {
    if (EmitTLSUnsupportedError && DeclAttrsMatchCUDAMode(getLangOpts(), NewVD))
      Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
           diag::err_thread_unsupported);
    // CUDA B.2.5: "__shared__ and __constant__ variables have implied static
    // storage [duration]."
    if (SC == SC_None && S->getFnParent() != nullptr &&
        (NewVD->hasAttr<CUDASharedAttr>() ||
         NewVD->hasAttr<CUDANocAttr>()||
         NewVD->hasAttr<CUDAConstantAttr>())) {
      NewVD->setStorageClass(SC_Static);
    }
  }

第4步:在CodeGenModule(llvm / tools / clang / lib / CodeGen / CodeGenModule.cpp)中添加NOC,以允许cuda_noc NVPTXAddrSpaceMap地址空间的访问}

    else if (D->hasAttr<CUDASharedAttr>())
      AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_shared);
    else if (D->hasAttr<CUDANocAttr>())
      AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_noc);
    else
      AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_device);
  }

  return AddrSpace;
}

第5步:将cuda_noc添加到NVPTXAddrSpaceMap数组以允许新类型的地址空间

static const unsigned NVPTXAddrSpaceMap[] = {
    1, // opencl_global
    3, // opencl_local
    4, // opencl_constant
    // FIXME: generic has to be added to the target
    0, // opencl_generic
    1, // cuda_device
    4, // cuda_constant
    3, // cuda_shared
    6, // cuda_noc
};

第6步:宏#define __noc__ __location__(noc)被添加到文件clang / lib / Headers / __ clang_cuda_runtime_wrapper.h中,其中包含来自CUDA的host_defines.h。

llvm源代码已成功编译和安装。但是当尝试使用内存类型__noc__编译CUDA源文件时,它会发出以下警告:

warning: unknown attribute 'noc' ignored [-Wunknown-attributes]
        __noc__ int c_shared[5];
        ^

/usr/local/bin/../lib/clang/3.8.0/include/__clang_cuda_runtime_wrapper.h:69:30: note: expanded from macro '__noc__'
#define __noc__ __location__(noc)
                             ^
1 warning generated.

从警告中可以看出__noc__被忽略。在生成的IR中,未观察到与addrspace(6)对应的__noc__

从调试printf放入文件clang / lib / Sema / SemaDeclAttr.cpp(步骤2),可以观察到AttributeList::AT_CUDANoc的情况没有被执行。

任何建议或直觉都可以提供很大帮助。在编译* .td文件中的输入的llvm源代码之前是否有任何脚本要显式运行,以显示为C ++源代码...

1 个答案:

答案 0 :(得分:4)

__location__(noc)扩展为__attribute__((noc))。这是GNU或gcc属性语法。所以问题在于这一行:

let Spellings = [Keyword<"noc">];

为了noc使用__location__宏,您应该使用GNU<"noc">代替Keyword<"noc">