diff --git a/lib/Target/NVPTX/MCTargetDesc/NVPTXBaseInfo.h b/lib/Target/NVPTX/MCTargetDesc/NVPTXBaseInfo.h index edf4a80b11e..ddb122f65b5 100644 --- a/lib/Target/NVPTX/MCTargetDesc/NVPTXBaseInfo.h +++ b/lib/Target/NVPTX/MCTargetDesc/NVPTXBaseInfo.h @@ -43,14 +43,16 @@ enum PropertyAnnotation { PROPERTY_ISSAMPLER, PROPERTY_ISREADONLY_IMAGE_PARAM, PROPERTY_ISWRITEONLY_IMAGE_PARAM, + PROPERTY_ISREADWRITE_IMAGE_PARAM, PROPERTY_ISKERNEL_FUNCTION, PROPERTY_ALIGN, + PROPERTY_MANAGED, // last property PROPERTY_LAST }; -const unsigned AnnotationNameLen = 8; // length of each annotation name +const unsigned AnnotationNameLen = 9; // length of each annotation name const char PropertyAnnotationNames[PROPERTY_LAST + 1][AnnotationNameLen + 1] = { "maxntidx", // PROPERTY_MAXNTID_X "maxntidy", // PROPERTY_MAXNTID_Y @@ -64,8 +66,10 @@ const char PropertyAnnotationNames[PROPERTY_LAST + 1][AnnotationNameLen + 1] = { "sampler", // PROPERTY_ISSAMPLER "rdoimage", // PROPERTY_ISREADONLY_IMAGE_PARAM "wroimage", // PROPERTY_ISWRITEONLY_IMAGE_PARAM + "rdwrimage", // PROPERTY_ISREADWRITE_IMAGE_PARAM "kernel", // PROPERTY_ISKERNEL_FUNCTION "align", // PROPERTY_ALIGN + "managed", // PROPERTY_MANAGED // last property "proplast", // PROPERTY_LAST diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 97e2cc69eff..78dda476132 100644 --- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -1010,6 +1010,8 @@ bool NVPTXAsmPrinter::doFinalization(Module &M) { for (i = 0; i < n; i++) global_list.insert(global_list.end(), gv_array[i]); + clearAnnotationCache(&M); + delete[] gv_array; return ret; diff --git a/lib/Target/NVPTX/NVPTXUtilities.cpp b/lib/Target/NVPTX/NVPTXUtilities.cpp index 60a517392fe..082d32ec2f0 100644 --- a/lib/Target/NVPTX/NVPTXUtilities.cpp +++ b/lib/Target/NVPTX/NVPTXUtilities.cpp @@ -22,9 +22,9 @@ #include #include #include -//#include #include "llvm/Support/ManagedStatic.h" #include "llvm/IR/InstIterator.h" +#include "llvm/Support/MutexGuard.h" using namespace llvm; @@ -33,8 +33,15 @@ typedef std::map global_val_annot_t; typedef std::map per_module_annot_t; ManagedStatic annotationCache; +static sys::Mutex Lock; + +void llvm::clearAnnotationCache(const llvm::Module *Mod) { + MutexGuard Guard(Lock); + annotationCache->erase(Mod); +} static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { + MutexGuard Guard(Lock); assert(md && "Invalid mdnode for annotation"); assert((md->getNumOperands() % 2) == 1 && "Invalid number of operands"); // start index = 1, to skip the global variable key @@ -60,6 +67,7 @@ static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { } static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { + MutexGuard Guard(Lock); NamedMDNode *NMD = m->getNamedMetadata(llvm::NamedMDForAnnotations); if (!NMD) return; @@ -92,6 +100,7 @@ static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { bool llvm::findOneNVVMAnnotation(const GlobalValue *gv, std::string prop, unsigned &retval) { + MutexGuard Guard(Lock); const Module *m = gv->getParent(); if ((*annotationCache).find(m) == (*annotationCache).end()) cacheAnnotationFromMD(m, gv); @@ -105,6 +114,7 @@ bool llvm::findOneNVVMAnnotation(const GlobalValue *gv, std::string prop, bool llvm::findAllNVVMAnnotation(const GlobalValue *gv, std::string prop, std::vector &retval) { + MutexGuard Guard(Lock); const Module *m = gv->getParent(); if ((*annotationCache).find(m) == (*annotationCache).end()) cacheAnnotationFromMD(m, gv); @@ -195,8 +205,37 @@ bool llvm::isImageWriteOnly(const llvm::Value &val) { return false; } +bool llvm::isImageReadWrite(const llvm::Value &val) { + if (const Argument *arg = dyn_cast(&val)) { + const Function *func = arg->getParent(); + std::vector annot; + if (llvm::findAllNVVMAnnotation(func, + llvm::PropertyAnnotationNames[ + llvm::PROPERTY_ISREADWRITE_IMAGE_PARAM], + annot)) { + if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) + return true; + } + } + return false; +} + bool llvm::isImage(const llvm::Value &val) { - return llvm::isImageReadOnly(val) || llvm::isImageWriteOnly(val); + return llvm::isImageReadOnly(val) || llvm::isImageWriteOnly(val) || + llvm::isImageReadWrite(val); +} + +bool llvm::isManaged(const llvm::Value &val) { + if(const GlobalValue *gv = dyn_cast(&val)) { + unsigned annot; + if(llvm::findOneNVVMAnnotation(gv, + llvm::PropertyAnnotationNames[llvm::PROPERTY_MANAGED], + annot)) { + assert((annot == 1) && "Unexpected annotation on a managed symbol"); + return true; + } + } + return false; } std::string llvm::getTextureName(const llvm::Value &val) { diff --git a/lib/Target/NVPTX/NVPTXUtilities.h b/lib/Target/NVPTX/NVPTXUtilities.h index a208004297d..446bfa1e112 100644 --- a/lib/Target/NVPTX/NVPTXUtilities.h +++ b/lib/Target/NVPTX/NVPTXUtilities.h @@ -28,6 +28,8 @@ namespace llvm { #define NVCL_IMAGE2D_READONLY_FUNCNAME "__is_image2D_readonly" #define NVCL_IMAGE3D_READONLY_FUNCNAME "__is_image3D_readonly" +void clearAnnotationCache(const llvm::Module *); + bool findOneNVVMAnnotation(const llvm::GlobalValue *, std::string, unsigned &); bool findAllNVVMAnnotation(const llvm::GlobalValue *, std::string, std::vector &); @@ -38,6 +40,8 @@ bool isSampler(const llvm::Value &); bool isImage(const llvm::Value &); bool isImageReadOnly(const llvm::Value &); bool isImageWriteOnly(const llvm::Value &); +bool isImageReadWrite(const llvm::Value &); +bool isManaged(const llvm::Value &); std::string getTextureName(const llvm::Value &); std::string getSurfaceName(const llvm::Value &);