[RISCV] Eliminate dead li after emitting VSETVLIs (#65934)
[llvm-project.git] / llvm / tools / llvm-exegesis / lib / SubprocessMemory.cpp
bloba49fa077257d002590335a44dbc7c4a536daf415
1 //===-- SubprocessMemory.cpp ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "SubprocessMemory.h"
10 #include "Error.h"
11 #include "llvm/Support/Error.h"
12 #include <cerrno>
14 #ifdef __linux__
15 #include <fcntl.h>
16 #include <sys/mman.h>
17 #include <unistd.h>
18 #endif
20 namespace llvm {
21 namespace exegesis {
23 #if defined(__linux__) && !defined(__ANDROID__)
25 Error SubprocessMemory::initializeSubprocessMemory(pid_t ProcessID) {
26 // Add the PID to the shared memory name so that if we're running multiple
27 // processes at the same time, they won't interfere with each other.
28 // This comes up particularly often when running the exegesis tests with
29 // llvm-lit
30 std::string AuxiliaryMemoryName = "/auxmem" + std::to_string(ProcessID);
31 int AuxiliaryMemoryFD = shm_open(AuxiliaryMemoryName.c_str(),
32 O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
33 if (AuxiliaryMemoryFD == -1)
34 return make_error<Failure>(
35 "Failed to create shared memory object for auxiliary memory: " +
36 Twine(strerror(errno)));
37 if (ftruncate(AuxiliaryMemoryFD, AuxiliaryMemorySize) != 0) {
38 return make_error<Failure>("Truncating the auxiliary memory failed: " +
39 Twine(strerror(errno)));
41 SharedMemoryNames.push_back(AuxiliaryMemoryName);
42 return Error::success();
45 Error SubprocessMemory::addMemoryDefinition(
46 std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
47 pid_t ProcessPID) {
48 SharedMemoryNames.reserve(MemoryDefinitions.size());
49 for (auto &[Name, MemVal] : MemoryDefinitions) {
50 std::string SharedMemoryName = "/" + std::to_string(ProcessPID) + "memdef" +
51 std::to_string(MemVal.Index);
52 SharedMemoryNames.push_back(SharedMemoryName);
53 int SharedMemoryFD =
54 shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
55 if (ftruncate(SharedMemoryFD, MemVal.SizeBytes) != 0) {
56 return make_error<Failure>("Truncating a memory definiton failed: " +
57 Twine(strerror(errno)));
60 char *SharedMemoryMapping =
61 (char *)mmap(NULL, MemVal.SizeBytes, PROT_READ | PROT_WRITE, MAP_SHARED,
62 SharedMemoryFD, 0);
63 // fill the buffer with the specified value
64 size_t CurrentByte = 0;
65 const size_t ValueWidthBytes = MemVal.Value.getBitWidth() / 8;
66 while (CurrentByte < MemVal.SizeBytes - ValueWidthBytes) {
67 memcpy(SharedMemoryMapping + CurrentByte, MemVal.Value.getRawData(),
68 ValueWidthBytes);
69 CurrentByte += ValueWidthBytes;
71 // fill the last section
72 memcpy(SharedMemoryMapping + CurrentByte, MemVal.Value.getRawData(),
73 MemVal.SizeBytes - CurrentByte);
74 if (munmap(SharedMemoryMapping, MemVal.SizeBytes) != 0) {
75 return make_error<Failure>(
76 "Unmapping a memory definition in the parent failed: " +
77 Twine(strerror(errno)));
80 return Error::success();
83 Expected<int> SubprocessMemory::setupAuxiliaryMemoryInSubprocess(
84 std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
85 pid_t ParentPID, int CounterFileDescriptor) {
86 std::string AuxiliaryMemoryName = "/auxmem" + std::to_string(ParentPID);
87 int AuxiliaryMemoryFileDescriptor =
88 shm_open(AuxiliaryMemoryName.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
89 if (AuxiliaryMemoryFileDescriptor == -1)
90 return make_error<Failure>(
91 "Getting file descriptor for auxiliary memory failed");
92 // set up memory value file descriptors
93 int *AuxiliaryMemoryMapping =
94 (int *)mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED,
95 AuxiliaryMemoryFileDescriptor, 0);
96 if ((intptr_t)AuxiliaryMemoryMapping == -1)
97 return make_error<Failure>("Mapping auxiliary memory failed");
98 AuxiliaryMemoryMapping[0] = CounterFileDescriptor;
99 for (auto &[Name, MemVal] : MemoryDefinitions) {
100 std::string MemoryValueName = "/" + std::to_string(ParentPID) + "memdef" +
101 std::to_string(MemVal.Index);
102 AuxiliaryMemoryMapping[AuxiliaryMemoryOffset + MemVal.Index] =
103 shm_open(MemoryValueName.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
104 if (AuxiliaryMemoryMapping[AuxiliaryMemoryOffset + MemVal.Index] == -1)
105 return make_error<Failure>("Mapping shared memory failed");
107 if (munmap(AuxiliaryMemoryMapping, 4096) == -1)
108 return make_error<Failure>("Unmapping auxiliary memory failed");
109 return AuxiliaryMemoryFileDescriptor;
112 SubprocessMemory::~SubprocessMemory() {
113 for (std::string SharedMemoryName : SharedMemoryNames) {
114 if (shm_unlink(SharedMemoryName.c_str()) != 0) {
115 errs() << "Failed to unlink shared memory section: " << strerror(errno)
116 << "\n";
121 #else
123 Error SubprocessMemory::initializeSubprocessMemory(pid_t ProcessPID) {
124 return make_error<Failure>(
125 "initializeSubprocessMemory is only supported on Linux");
128 Error SubprocessMemory::addMemoryDefinition(
129 std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
130 pid_t ProcessPID) {
131 return make_error<Failure>("addMemoryDefinitions is only supported on Linux");
134 Expected<int> SubprocessMemory::setupAuxiliaryMemoryInSubprocess(
135 std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
136 pid_t ParentPID, int CounterFileDescriptor) {
137 return make_error<Failure>(
138 "setupAuxiliaryMemoryInSubprocess is only supported on Linux");
141 SubprocessMemory::~SubprocessMemory() {}
143 #endif // defined(__linux__) && !defined(__ANDROID__)
145 } // namespace exegesis
146 } // namespace llvm