|
17 | 17 | #include "llvm/ADT/StringSwitch.h" |
18 | 18 | #include "llvm/BinaryFormat/Dwarf.h" |
19 | 19 | #include "llvm/IR/AttributeMask.h" |
| 20 | +#include "llvm/IR/CallingConv.h" |
20 | 21 | #include "llvm/IR/Constants.h" |
21 | 22 | #include "llvm/IR/DebugInfo.h" |
22 | 23 | #include "llvm/IR/DebugInfoMetadata.h" |
@@ -5019,6 +5020,72 @@ bool llvm::UpgradeDebugInfo(Module &M) { |
5019 | 5020 | return Modified; |
5020 | 5021 | } |
5021 | 5022 |
|
| 5023 | +bool static upgradeSingleNVVMAnnotation(GlobalValue *GV, StringRef K, |
| 5024 | + const Metadata *V) { |
| 5025 | + if (K == "kernel") { |
| 5026 | + if (!mdconst::extract<ConstantInt>(V)->isZero()) |
| 5027 | + cast<Function>(GV)->setCallingConv(CallingConv::PTX_Kernel); |
| 5028 | + return true; |
| 5029 | + } |
| 5030 | + if (K == "align") { |
| 5031 | + // V is a bitfeild specifying two 16-bit values. The alignment value is |
| 5032 | + // specfied in low 16-bits, The index is specified in the high bits. For the |
| 5033 | + // index, 0 indicates the return value while higher values correspond to |
| 5034 | + // each parameter (idx = param + 1). |
| 5035 | + const uint64_t AlignIdxValuePair = |
| 5036 | + mdconst::extract<ConstantInt>(V)->getZExtValue(); |
| 5037 | + const unsigned Idx = (AlignIdxValuePair >> 16); |
| 5038 | + const Align StackAlign = Align(AlignIdxValuePair & 0xFFFF); |
| 5039 | + // TODO: Skip adding the stackalign attribute for returns, for now. |
| 5040 | + if (!Idx) |
| 5041 | + return false; |
| 5042 | + cast<Function>(GV)->addAttributeAtIndex( |
| 5043 | + Idx, Attribute::getWithStackAlignment(GV->getContext(), StackAlign)); |
| 5044 | + return true; |
| 5045 | + } |
| 5046 | + |
| 5047 | + return false; |
| 5048 | +} |
| 5049 | + |
| 5050 | +void llvm::UpgradeNVVMAnnotations(Module &M) { |
| 5051 | + NamedMDNode *NamedMD = M.getNamedMetadata("nvvm.annotations"); |
| 5052 | + if (!NamedMD) |
| 5053 | + return; |
| 5054 | + |
| 5055 | + SmallVector<MDNode *, 8> NewNodes; |
| 5056 | + SmallSet<const MDNode *, 8> SeenNodes; |
| 5057 | + for (MDNode *MD : NamedMD->operands()) { |
| 5058 | + if (!SeenNodes.insert(MD).second) |
| 5059 | + continue; |
| 5060 | + |
| 5061 | + auto *GV = mdconst::dyn_extract_or_null<GlobalValue>(MD->getOperand(0)); |
| 5062 | + if (!GV) |
| 5063 | + continue; |
| 5064 | + |
| 5065 | + assert((MD->getNumOperands() % 2) == 1 && "Invalid number of operands"); |
| 5066 | + |
| 5067 | + SmallVector<Metadata *, 8> NewOperands{MD->getOperand(0)}; |
| 5068 | + // Each nvvm.annotations metadata entry will be of the following form: |
| 5069 | + // !{ ptr @gv, !"key1", value1, !"key2", value2, ... } |
| 5070 | + // start index = 1, to skip the global variable key |
| 5071 | + // increment = 2, to skip the value for each property-value pairs |
| 5072 | + for (unsigned j = 1, je = MD->getNumOperands(); j < je; j += 2) { |
| 5073 | + MDString *K = cast<MDString>(MD->getOperand(j)); |
| 5074 | + const MDOperand &V = MD->getOperand(j + 1); |
| 5075 | + bool Upgraded = upgradeSingleNVVMAnnotation(GV, K->getString(), V); |
| 5076 | + if (!Upgraded) |
| 5077 | + NewOperands.append({K, V}); |
| 5078 | + } |
| 5079 | + |
| 5080 | + if (NewOperands.size() > 1) |
| 5081 | + NewNodes.push_back(MDNode::get(M.getContext(), NewOperands)); |
| 5082 | + } |
| 5083 | + |
| 5084 | + NamedMD->clearOperands(); |
| 5085 | + for (MDNode *N : NewNodes) |
| 5086 | + NamedMD->addOperand(N); |
| 5087 | +} |
| 5088 | + |
5022 | 5089 | /// This checks for objc retain release marker which should be upgraded. It |
5023 | 5090 | /// returns true if module is modified. |
5024 | 5091 | static bool upgradeRetainReleaseMarker(Module &M) { |
|
0 commit comments