[PATCH v2 34/50] helper-to-tcg: TcgGenPass, map arguments to TCG
Anton Johansson via qemu development <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Mapping for arguments is slighty different than other `Value`s and depend on function annotations, perform it as a separe pass. Signed-off-by: Anton Johansson <[email protected]> --- subprojects/helper-to-tcg/meson.build | 1 + .../src/TcgGenPass/MapArguments.cpp | 122 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 subprojects/helper-to-tcg/src/TcgGenPass/MapArguments.cpp diff --git a/subprojects/helper-to-tcg/meson.build b/subprojects/helper-to-tcg/meson.build index c03a4d5df6..22190025d0 100644 --- a/subprojects/helper-to-tcg/meson.build +++ b/subprojects/helper-to-tcg/meson.build @@ -51,6 +51,7 @@ sources = [ 'src/TcgGenPass/TcgGenPass.cpp', 'src/TcgGenPass/LinearizeBlocks.cpp', 'src/TcgGenPass/TcgEmit.cpp', + 'src/TcgGenPass/MapArguments.cpp', ] clang = bindir / 'clang' diff --git a/subprojects/helper-to-tcg/src/TcgGenPass/MapArguments.cpp b/subprojects/helper-to-tcg/src/TcgGenPass/MapArguments.cpp new file mode 100644 index 0000000000..04aa8cf10c --- /dev/null +++ b/subprojects/helper-to-tcg/src/TcgGenPass/MapArguments.cpp @@ -0,0 +1,122 @@ +// +// Copyright(c) 2026 rev.ng Labs Srl. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, see <http://www.gnu.org/licenses/>. +// + +#include "DebugInfo.hpp" +#include "ValueMapping.hpp" + +#include "Error.hpp" +#include "FunctionAnnotation.hpp" +#include "TcgType.hpp" + +#include <llvm/IR/Constants.h> +#include <llvm/IR/DerivedTypes.h> +#include <llvm/IR/Function.h> +#include <llvm/IR/Module.h> + +#define DEBUG_TYPE "map-arguments" + +// +// Map Arguments +// +// Assign `TcgV`s to function arguments, taking function annotations into +// account to force types. Mapping them early and separately both makes sure +// that no other pass accidently assign to them, and separates out any special +// case logic that's necessary. +// + +using namespace llvm; + +static Expected<TcgV> mapIntegerArgument(TempAllocationData &TAD, + const DebugInfoMapTy &DebugInfo, + const Argument *Arg, + uint8_t Annotations) { + auto *IntTy = cast<IntegerType>(Arg->getType()); + auto Size = ValueSize::fromLlvmType(IntTy); + if (!Size) { + return Size.takeError(); + } + + StringRef Name = getDebugVarName(DebugInfo, Arg); + + if ((Annotations & (uint8_t)ArgumentAnnotation::Immediate) != 0) { + auto Tcg = TcgV::makeImmediate(Name, *Size); + return TAD.map(Arg, Tcg); + } else { + auto Tcg = TcgV::makeTemp(*Size, IrValue); + Tcg.Name = Name; + return TAD.map(Arg, Tcg); + } +} + +static Expected<TcgV> mapPointerArgument(TempAllocationData &TAD, + const DebugInfoMapTy &DebugInfo, + const Argument *Arg, + uint8_t Annotations) { + // If the value has an associated name from the debug information, use it + StringRef Name{}; + if (auto It = DebugInfo.find(Arg); It != DebugInfo.end()) { + Name = It->second.VarName; + } + + if ((Annotations & (uint8_t)ArgumentAnnotation::PtrToOffset) != 0) { + auto Tcg = TcgV::makeVector({}); + Tcg.Name = Name; + return TAD.map(Arg, Tcg); + } else { + auto Tcg = TcgV::makeTemp({}, IrPtr); + Tcg.Name = Name; + return TAD.map(Arg, Tcg); + } +} + +static Expected<TcgV> mapArgument(TempAllocationData &Data, + const DebugInfoMapTy &DebugInfo, + const Argument *Arg, uint8_t Annotations) { + // We only map each argument once, assert it's not been mapped previously. + assert(!Data.Map.count(Arg)); + + Type *Ty = Arg->getType(); + if (isa<IntegerType>(Ty)) { + return mapIntegerArgument(Data, DebugInfo, Arg, Annotations); + } else if (isa<PointerType>(Ty)) { + return mapPointerArgument(Data, DebugInfo, Arg, Annotations); + } + + return mkError("Unable to map value ", Arg); +} + +Error mapArguments(const llvm::Function &F, + const AnnotationMapTy &AnnotationMap, + const DebugInfoMapTy &DebugInfo, TempAllocationData &Data) { + // Map arguments + for (size_t I = 0; I < F.arg_size(); ++I) { + const Argument *Arg = F.getArg(I); + auto It = AnnotationMap.find(&F); + const uint8_t Annotations = + (It != AnnotationMap.end()) ? It->second.getArgFlag(I) : 0; + Expected<TcgV> TcgArg = mapArgument(Data, DebugInfo, Arg, Annotations); + if (!TcgArg) { + return TcgArg.takeError(); + } + LLVM_DEBUG({ + dbgs() << "Mapped argument " << *Arg << " to: \n"; + TcgArg->dump(dbgs()); + }); + } + + return Error::success(); +} -- 2.52.0