-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBenchPlugin.c
More file actions
130 lines (120 loc) · 4.98 KB
/
Copy pathBenchPlugin.c
File metadata and controls
130 lines (120 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* First-release ABI microbenchmark example.
*
* The pass deliberately performs many read-only table calls and preserves all
* analyses. It is useful for measuring plugin call overhead without changing
* the compiled program.
*/
#include "neverc/Plugin/NevercPluginAPI.h"
#include <stddef.h>
#include <string.h>
#define PLUGIN_ID "org.neverc.example.abi-bench"
#define SV(Text) \
(NevercStringView) { (Text), (uint64_t)(sizeof(Text) - 1) }
static const NevercIRPassAPI *PassAPI;
static const NevercCoreAPI *CoreAPI;
static NevercStatus failure(NevercStatusCode Code) {
NevercStatus Status = neverc_status_ok();
Status.Code = Code;
return Status;
}
static NevercStatus NEVERC_CALL
run_benchmark(const NevercIRPassInvocation *Invocation,
NevercIRPreservedAnalyses *OutPreserved, void *UserData) {
NevercStringView Identifier = {0};
NevercDiagnosticDescriptor Diagnostic;
NevercDiagnosticHandle DiagnosticHandle = {0};
NevercStatus Status = neverc_status_ok();
uint32_t Iteration;
(void)UserData;
if (!Invocation || !Invocation->Core || !OutPreserved || !CoreAPI)
return failure(NEVERC_STATUS_INVALID_ARGUMENT);
for (Iteration = 0; Iteration != 10000; ++Iteration) {
Status = Invocation->Core->GetModuleIdentifier(
Invocation->Core->Context, Invocation->Task, &Identifier);
if (Status.Code != NEVERC_STATUS_OK)
return Status;
}
memset(&Diagnostic, 0, sizeof(Diagnostic));
Diagnostic.Header =
(NevercABITableHeader){sizeof(Diagnostic), NEVERC_CORE_API_MAJOR,
NEVERC_CORE_API_MINOR, 0};
Diagnostic.Severity = NEVERC_DIAGNOSTIC_REMARK;
Diagnostic.Code = 5201;
Diagnostic.PluginID = SV(PLUGIN_ID);
Diagnostic.Message =
SV("BenchPlugin completed 10000 typed IR table calls");
Status = CoreAPI->EmitDiagnostic(CoreAPI->Context, &Diagnostic,
&DiagnosticHandle);
if (Status.Code != NEVERC_STATUS_OK)
return Status;
memset(OutPreserved, 0, sizeof(*OutPreserved));
OutPreserved->Header =
(NevercABITableHeader){sizeof(*OutPreserved), NEVERC_IR_PASS_API_MAJOR,
NEVERC_IR_PASS_API_MINOR, 0};
OutPreserved->Flags = NEVERC_IR_PRESERVE_ALL;
return neverc_status_ok();
}
static NevercStatus NEVERC_CALL
register_plugin(const NevercCoreAPI *Core, const NevercRegistrarAPI *Registrar,
void *RegistrarContext, void *PluginProcessState) {
NevercIRPassDescriptor Descriptor;
(void)Registrar;
(void)PluginProcessState;
if (!Core || !PassAPI)
return failure(NEVERC_STATUS_INVALID_ARGUMENT);
CoreAPI = Core;
memset(&Descriptor, 0, sizeof(Descriptor));
Descriptor.Header =
(NevercABITableHeader){sizeof(Descriptor), NEVERC_IR_PASS_API_MAJOR,
NEVERC_IR_PASS_API_MINOR, 0};
Descriptor.PassID = SV("bench.typed-table-calls");
Descriptor.Phase =
(NevercInterfaceID){NEVERC_PHASE_IR_PASS_PRE_CODEGEN_HIGH,
NEVERC_PHASE_IR_PASS_PRE_CODEGEN_LOW};
Descriptor.Level = NEVERC_IR_PASS_LEVEL_MODULE;
Descriptor.Deterministic = NEVERC_TRUE;
Descriptor.Run = run_benchmark;
return PassAPI->RegisterPass(PassAPI->Context, RegistrarContext, &Descriptor);
}
NEVERC_EXPORT NevercStatus NEVERC_CALL neverc_plugin_entry(
const NevercBootstrapAPI *Bootstrap, NevercPluginDescriptor *OutPlugin) {
NevercPluginDescriptor Descriptor;
const void *Table = NULL;
uint16_t Minor = 0;
uint64_t StructSize = 0;
uint32_t Capacity;
size_t Writable;
NevercStatus Status;
if (!Bootstrap || !Bootstrap->QueryInterface || !OutPlugin ||
OutPlugin->Header.StructSize < sizeof(uint32_t))
return failure(NEVERC_STATUS_INVALID_ARGUMENT);
Status = Bootstrap->QueryInterface(
Bootstrap->Context,
(NevercInterfaceID){NEVERC_INTERFACE_IR_PASS_HIGH,
NEVERC_INTERFACE_IR_PASS_LOW},
NEVERC_IR_PASS_API_MAJOR, NEVERC_IR_PASS_API_MINOR, &Table, &Minor,
&StructSize);
if (Status.Code != NEVERC_STATUS_OK)
return Status;
if (!Table ||
StructSize < offsetof(NevercIRPassAPI, RegisterPass) +
sizeof(((NevercIRPassAPI *)0)->RegisterPass))
return failure(NEVERC_STATUS_ABI_MISMATCH);
PassAPI = (const NevercIRPassAPI *)Table;
Capacity = OutPlugin->Header.StructSize;
memset(&Descriptor, 0, sizeof(Descriptor));
Descriptor.Header =
(NevercABITableHeader){sizeof(Descriptor), NEVERC_PLUGIN_ABI_MAJOR,
NEVERC_PLUGIN_ABI_MINOR, 0};
Descriptor.PluginID = SV(PLUGIN_ID);
Descriptor.DisplayName = SV("NeverC first-release ABI benchmark");
Descriptor.Version.Major = 1;
Descriptor.Concurrency = NEVERC_CONCURRENCY_SESSION_SERIAL;
Descriptor.Reentrancy = NEVERC_REENTRANCY_NONE;
Descriptor.Register = register_plugin;
Writable = Capacity < sizeof(Descriptor) ? Capacity : sizeof(Descriptor);
memcpy(OutPlugin, &Descriptor, Writable);
OutPlugin->Header.StructSize = sizeof(Descriptor);
return neverc_status_ok();
}