35
35
#include " llvm/Support/Process.h"
36
36
#include " llvm/Support/Program.h"
37
37
#include " llvm/Support/TargetSelect.h"
38
+ #include " llvm/Support/Timer.h"
38
39
#include " llvm/Support/raw_ostream.h"
39
40
40
41
#include < cstdint>
41
42
#include < cstdlib>
43
+ #include < optional>
42
44
43
45
using namespace mlir ;
44
46
using namespace mlir ::NVVM;
@@ -220,6 +222,16 @@ class NVPTXSerializer : public SerializeGPUModuleBase {
220
222
std::optional<SmallVector<char , 0 >>
221
223
moduleToObject (llvm::Module &llvmModule) override ;
222
224
225
+ // / Get LLVMIR->ISA performance result.
226
+ // / Return nullopt if moduleToObject has not been called or the target format
227
+ // / is LLVMIR.
228
+ std::optional<int64_t > getLLVMIRToISATimeInMs ();
229
+
230
+ // / Get ISA->Binary performance result.
231
+ // / Return nullopt if moduleToObject has not been called or the target format
232
+ // / is LLVMIR or ISA.
233
+ std::optional<int64_t > getISAToBinaryTimeInMs ();
234
+
223
235
private:
224
236
using TmpFile = std::pair<llvm::SmallString<128 >, llvm::FileRemover>;
225
237
@@ -235,13 +247,20 @@ class NVPTXSerializer : public SerializeGPUModuleBase {
235
247
236
248
// / Target options.
237
249
gpu::TargetOptions targetOptions;
250
+
251
+ // / LLVMIR->ISA perf result.
252
+ std::optional<int64_t > llvmToISATimeInMs;
253
+
254
+ // / ISA->Binary perf result.
255
+ std::optional<int64_t > isaToBinaryTimeInMs;
238
256
};
239
257
} // namespace
240
258
241
259
NVPTXSerializer::NVPTXSerializer (Operation &module, NVVMTargetAttr target,
242
260
const gpu::TargetOptions &targetOptions)
243
261
: SerializeGPUModuleBase(module, target, targetOptions),
244
- targetOptions(targetOptions) {}
262
+ targetOptions(targetOptions), llvmToISATimeInMs(std::nullopt),
263
+ isaToBinaryTimeInMs(std::nullopt) {}
245
264
246
265
std::optional<NVPTXSerializer::TmpFile>
247
266
NVPTXSerializer::createTemp (StringRef name, StringRef suffix) {
@@ -256,6 +275,14 @@ NVPTXSerializer::createTemp(StringRef name, StringRef suffix) {
256
275
return TmpFile (filename, llvm::FileRemover (filename.c_str ()));
257
276
}
258
277
278
+ std::optional<int64_t > NVPTXSerializer::getLLVMIRToISATimeInMs () {
279
+ return llvmToISATimeInMs;
280
+ }
281
+
282
+ std::optional<int64_t > NVPTXSerializer::getISAToBinaryTimeInMs () {
283
+ return isaToBinaryTimeInMs;
284
+ }
285
+
259
286
gpu::GPUModuleOp NVPTXSerializer::getOperation () {
260
287
return dyn_cast<gpu::GPUModuleOp>(&SerializeGPUModuleBase::getOperation ());
261
288
}
@@ -618,6 +645,10 @@ NVPTXSerializer::compileToBinaryNVPTX(const std::string &ptxCode) {
618
645
619
646
std::optional<SmallVector<char , 0 >>
620
647
NVPTXSerializer::moduleToObject (llvm::Module &llvmModule) {
648
+ llvm::Timer moduleToObjectTimer (
649
+ " moduleToObjectTimer" ,
650
+ " Timer for perf llvm-ir -> isa and isa -> binary." );
651
+ moduleToObjectTimer.startTimer ();
621
652
// Return LLVM IR if the compilation target is `offload`.
622
653
#define DEBUG_TYPE " serialize-to-llvm"
623
654
LLVM_DEBUG ({
@@ -650,6 +681,11 @@ NVPTXSerializer::moduleToObject(llvm::Module &llvmModule) {
650
681
getOperation ().emitError () << " Failed translating the module to ISA." ;
651
682
return std::nullopt;
652
683
}
684
+
685
+ moduleToObjectTimer.stopTimer ();
686
+ llvmToISATimeInMs = moduleToObjectTimer.getTotalTime ().getWallTime () * 1000 ;
687
+ moduleToObjectTimer.clear ();
688
+ moduleToObjectTimer.startTimer ();
653
689
if (isaCallback)
654
690
isaCallback (serializedISA.value ());
655
691
@@ -669,17 +705,24 @@ NVPTXSerializer::moduleToObject(llvm::Module &llvmModule) {
669
705
return SmallVector<char , 0 >(bin.begin (), bin.end ());
670
706
}
671
707
708
+ std::optional<SmallVector<char , 0 >> result;
672
709
// Compile to binary.
673
710
#if MLIR_ENABLE_NVPTXCOMPILER
674
- return compileToBinaryNVPTX (*serializedISA);
711
+ result = compileToBinaryNVPTX (*serializedISA);
675
712
#else
676
- return compileToBinary (*serializedISA);
713
+ result = compileToBinary (*serializedISA);
677
714
#endif // MLIR_ENABLE_NVPTXCOMPILER
715
+
716
+ moduleToObjectTimer.stopTimer ();
717
+ isaToBinaryTimeInMs = moduleToObjectTimer.getTotalTime ().getWallTime () * 1000 ;
718
+ moduleToObjectTimer.clear ();
719
+ return result;
678
720
}
679
721
680
722
std::optional<SmallVector<char , 0 >>
681
723
NVVMTargetAttrImpl::serializeToObject (Attribute attribute, Operation *module,
682
724
const gpu::TargetOptions &options) const {
725
+ Builder builder (attribute.getContext ());
683
726
assert (module && " The module must be non null." );
684
727
if (!module)
685
728
return std::nullopt;
@@ -689,7 +732,16 @@ NVVMTargetAttrImpl::serializeToObject(Attribute attribute, Operation *module,
689
732
}
690
733
NVPTXSerializer serializer (*module, cast<NVVMTargetAttr>(attribute), options);
691
734
serializer.init ();
692
- return serializer.run ();
735
+ std::optional<SmallVector<char , 0 >> result = serializer.run ();
736
+ auto llvmToISATimeInMs = serializer.getLLVMIRToISATimeInMs ();
737
+ if (llvmToISATimeInMs.has_value ())
738
+ module->setAttr (" LLVMIRToISATimeInMs" ,
739
+ builder.getI64IntegerAttr (*llvmToISATimeInMs));
740
+ auto isaToBinaryTimeInMs = serializer.getISAToBinaryTimeInMs ();
741
+ if (isaToBinaryTimeInMs.has_value ())
742
+ module->setAttr (" ISAToBinaryTimeInMs" ,
743
+ builder.getI64IntegerAttr (*isaToBinaryTimeInMs));
744
+ return result;
693
745
}
694
746
695
747
Attribute
@@ -700,7 +752,7 @@ NVVMTargetAttrImpl::createObject(Attribute attribute, Operation *module,
700
752
gpu::CompilationTarget format = options.getCompilationTarget ();
701
753
DictionaryAttr objectProps;
702
754
Builder builder (attribute.getContext ());
703
- SmallVector<NamedAttribute, 2 > properties;
755
+ SmallVector<NamedAttribute, 4 > properties;
704
756
if (format == gpu::CompilationTarget::Assembly)
705
757
properties.push_back (
706
758
builder.getNamedAttr (" O" , builder.getI32IntegerAttr (target.getO ())));
@@ -709,6 +761,14 @@ NVVMTargetAttrImpl::createObject(Attribute attribute, Operation *module,
709
761
properties.push_back (builder.getNamedAttr (gpu::elfSectionName,
710
762
builder.getStringAttr (section)));
711
763
764
+ for (const auto *perfName : {" LLVMIRToISATimeInMs" , " ISAToBinaryTimeInMs" }) {
765
+ if (module->hasAttr (perfName)) {
766
+ IntegerAttr attr = llvm::dyn_cast<IntegerAttr>(module->getAttr (perfName));
767
+ properties.push_back (builder.getNamedAttr (
768
+ perfName, builder.getI64IntegerAttr (attr.getInt ())));
769
+ }
770
+ }
771
+
712
772
if (!properties.empty ())
713
773
objectProps = builder.getDictionaryAttr (properties);
714
774
0 commit comments