[MIRVRegNamer] Experimental MachineInstr stable hashing (Fowler-Noll-Vo)

This hashing scheme has been useful out of tree, and I want to start
experimenting with it. Specifically I want to experiment on the
MIRVRegNamer, MIRCanononicalizer, and eventually the MachineOutliner.

This diff is a first step, that optionally brings stable hashing to the
MIRVRegNamer (and as a result, the MIRCanonicalizer).  We've tested this
hashing scheme on a lot of MachineOperand types that llvm::hash_value
can not handle in a stable manner.

This stable hashing was also the basis for

"Global Machine Outliner for ThinLTO" in EuroLLVM 2020

http://llvm.org/devmtg/2020-04/talks.html#TechTalk_58

Credits: Kyungwoo Lee, Nikolai Tillmann

Differential Revision: https://reviews.llvm.org/D86952
This commit is contained in:
Puyan Lotfi
2020-09-03 15:38:52 -04:00
committed by Puyan Lotfi
parent c9771391ce
commit 7fff1fbd3c
20 changed files with 379 additions and 8 deletions

View File

@@ -759,6 +759,11 @@ public:
bool isKill = false, bool isDead = false,
bool isUndef = false, bool isDebug = false);
/// getTargetIndexName - If this MachineOperand is a TargetIndex that has a
/// name, attempt to get the name. Returns nullptr if the TargetIndex does not
/// have a name. Asserts if MO is not a TargetIndex.
const char *getTargetIndexName() const;
//===--------------------------------------------------------------------===//
// Construction methods.
//===--------------------------------------------------------------------===//

View File

@@ -0,0 +1,28 @@
//===------------ MIRVRegNamerUtils.h - MIR VReg Renaming Utilities -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Stable hashing for MachineInstr and MachineOperand. Useful or getting a
// hash across runs, modules, etc.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINESTABLEHASH_H
#define LLVM_CODEGEN_MACHINESTABLEHASH_H
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/StableHashing.h"
namespace llvm {
stable_hash stableHashValue(const MachineOperand &MO);
stable_hash stableHashValue(const MachineInstr &MI, bool HashVRegs = false,
bool HashConstantPoolIndices = false,
bool HashMemOperands = false);
} // namespace llvm
#endif

View File

@@ -0,0 +1,112 @@
//===- llvm/CodeGen/StableHashing.h - Utilities for stable hashing * C++ *-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file provides types and functions for computing and combining stable
// hashes. Stable hashes can be useful for hashing across different modules,
// processes, or compiler runs.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_STABLEHASHING_H
#define LLVM_CODEGEN_STABLEHASHING_H
#include "llvm/ADT/StringRef.h"
namespace llvm {
/// An opaque object representing a stable hash code. It can be serialized,
/// deserialized, and is stable across processes and executions.
using stable_hash = uint64_t;
// Implementation details
namespace hashing {
namespace detail {
// Stable hashes are based on the 64-bit FNV-1 hash:
// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
const uint64_t FNV_PRIME_64 = 1099511628211u;
const uint64_t FNV_OFFSET_64 = 14695981039346656037u;
inline void stable_hash_append(stable_hash &Hash, const char Value) {
Hash = Hash ^ (Value & 0xFF);
Hash = Hash * FNV_PRIME_64;
}
inline void stable_hash_append(stable_hash &Hash, stable_hash Value) {
for (unsigned I = 0; I < 8; ++I) {
stable_hash_append(Hash, (const char)Value);
Value >>= 8;
}
}
} // namespace detail
} // namespace hashing
inline stable_hash stable_hash_combine(stable_hash A, stable_hash B) {
stable_hash Hash = hashing::detail::FNV_OFFSET_64;
hashing::detail::stable_hash_append(Hash, A);
hashing::detail::stable_hash_append(Hash, B);
return Hash;
}
inline stable_hash stable_hash_combine(stable_hash A, stable_hash B,
stable_hash C) {
stable_hash Hash = hashing::detail::FNV_OFFSET_64;
hashing::detail::stable_hash_append(Hash, A);
hashing::detail::stable_hash_append(Hash, B);
hashing::detail::stable_hash_append(Hash, C);
return Hash;
}
inline stable_hash stable_hash_combine(stable_hash A, stable_hash B,
stable_hash C, stable_hash D) {
stable_hash Hash = hashing::detail::FNV_OFFSET_64;
hashing::detail::stable_hash_append(Hash, A);
hashing::detail::stable_hash_append(Hash, B);
hashing::detail::stable_hash_append(Hash, C);
hashing::detail::stable_hash_append(Hash, D);
return Hash;
}
/// Compute a stable_hash for a sequence of values.
///
/// This hashes a sequence of values. It produces the same stable_hash as
/// 'stable_hash_combine(a, b, c, ...)', but can run over arbitrary sized
/// sequences and is significantly faster given pointers and types which
/// can be hashed as a sequence of bytes.
template <typename InputIteratorT>
stable_hash stable_hash_combine_range(InputIteratorT First,
InputIteratorT Last) {
stable_hash Hash = hashing::detail::FNV_OFFSET_64;
for (auto I = First; I != Last; ++I)
hashing::detail::stable_hash_append(Hash, *I);
return Hash;
}
inline stable_hash stable_hash_combine_array(const stable_hash *P, size_t C) {
stable_hash Hash = hashing::detail::FNV_OFFSET_64;
for (size_t I = 0; I < C; ++I)
hashing::detail::stable_hash_append(Hash, P[I]);
return Hash;
}
inline stable_hash stable_hash_combine_string(const StringRef &S) {
return stable_hash_combine_range(S.begin(), S.end());
}
inline stable_hash stable_hash_combine_string(const char *C) {
stable_hash Hash = hashing::detail::FNV_OFFSET_64;
while (*C)
hashing::detail::stable_hash_append(Hash, *(C++));
return Hash;
}
} // namespace llvm
#endif

View File

@@ -136,6 +136,7 @@ add_llvm_component_library(LLVMCodeGen
RegisterPressure.cpp
RegisterScavenging.cpp
RenameIndependentSubregs.cpp
MachineStableHash.cpp
MIRVRegNamerUtils.cpp
MIRNamerPass.cpp
MIRCanonicalizerPass.cpp

View File

@@ -8,6 +8,7 @@
#include "MIRVRegNamerUtils.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineStableHash.h"
#include "llvm/IR/Constants.h"
#include "llvm/Support/Debug.h"
@@ -15,6 +16,11 @@ using namespace llvm;
#define DEBUG_TYPE "mir-vregnamer-utils"
static cl::opt<bool>
UseStableNamerHash("mir-vreg-namer-use-stable-hash", cl::init(false),
cl::Hidden,
cl::desc("Use Stable Hashing for MIR VReg Renaming"));
using VRegRenameMap = std::map<unsigned, unsigned>;
bool VRegRenamer::doVRegRenaming(const VRegRenameMap &VRM) {
@@ -52,6 +58,14 @@ std::string VRegRenamer::getInstructionOpcodeHash(MachineInstr &MI) {
std::string S;
raw_string_ostream OS(S);
if (UseStableNamerHash) {
auto Hash = stableHashValue(MI, /* HashVRegs */ true,
/* HashConstantPoolIndices */ true,
/* HashMemOperands */ true);
assert(Hash && "Expected non-zero Hash");
return std::to_string(Hash).substr(0, 5);
}
// Gets a hashable artifact from a given MachineOperand (ie an unsigned).
auto GetHashableMO = [this](const MachineOperand &MO) -> unsigned {
switch (MO.getType()) {

View File

@@ -415,6 +415,11 @@ static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
return nullptr;
}
const char *MachineOperand::getTargetIndexName() const {
const MachineFunction *MF = getMFIfAvailable(*this);
return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
}
static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
for (const auto &I : Flags) {
@@ -823,7 +828,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
OS << "target-index(";
const char *Name = "<unknown>";
if (const MachineFunction *MF = getMFIfAvailable(*this))
if (const auto *TargetIndexName = getTargetIndexName(*MF, getIndex()))
if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
Name = TargetIndexName;
OS << Name << ')';
printOperandOffset(OS, getOffset());

View File

@@ -0,0 +1,193 @@
//===- lib/CodeGen/MachineStableHash.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Stable hashing for MachineInstr and MachineOperand. Useful or getting a
// hash across runs, modules, etc.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineStableHash.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/MIRFormatter.h"
#include "llvm/CodeGen/MIRPrinter.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/StableHashing.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/Target/TargetIntrinsicInfo.h"
#include "llvm/Target/TargetMachine.h"
#define DEBUG_TYPE "machine-stable-hash"
using namespace llvm;
STATISTIC(StableHashBailingMachineBasicBlock,
"Number of encountered unsupported MachineOperands that were "
"MachineBasicBlocks while computing stable hashes");
STATISTIC(StableHashBailingConstantPoolIndex,
"Number of encountered unsupported MachineOperands that were "
"ConstantPoolIndex while computing stable hashes");
STATISTIC(StableHashBailingTargetIndexNoName,
"Number of encountered unsupported MachineOperands that were "
"TargetIndex with no name");
STATISTIC(StableHashBailingGlobalAddress,
"Number of encountered unsupported MachineOperands that were "
"GlobalAddress while computing stable hashes");
STATISTIC(StableHashBailingBlockAddress,
"Number of encountered unsupported MachineOperands that were "
"BlockAddress while computing stable hashes");
STATISTIC(StableHashBailingMetadataUnsupported,
"Number of encountered unsupported MachineOperands that were "
"Metadata of an unsupported kind while computing stable hashes");
stable_hash llvm::stableHashValue(const MachineOperand &MO) {
switch (MO.getType()) {
case MachineOperand::MO_Register:
if (Register::isVirtualRegister(MO.getReg())) {
const MachineRegisterInfo &MRI = MO.getParent()->getMF()->getRegInfo();
return MRI.getVRegDef(MO.getReg())->getOpcode();
}
// Register operands don't have target flags.
return stable_hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(),
MO.isDef());
case MachineOperand::MO_Immediate:
return stable_hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
case MachineOperand::MO_CImmediate:
case MachineOperand::MO_FPImmediate: {
auto Val = MO.isCImm() ? MO.getCImm()->getValue()
: MO.getFPImm()->getValueAPF().bitcastToAPInt();
auto ValHash =
stable_hash_combine_array(Val.getRawData(), Val.getNumWords());
return hash_combine(MO.getType(), MO.getTargetFlags(), ValHash);
}
case MachineOperand::MO_MachineBasicBlock:
StableHashBailingMachineBasicBlock++;
return 0;
case MachineOperand::MO_ConstantPoolIndex:
StableHashBailingConstantPoolIndex++;
return 0;
case MachineOperand::MO_BlockAddress:
StableHashBailingBlockAddress++;
return 0;
case MachineOperand::MO_Metadata:
StableHashBailingMetadataUnsupported++;
return 0;
case MachineOperand::MO_GlobalAddress:
StableHashBailingGlobalAddress++;
return 0;
case MachineOperand::MO_TargetIndex: {
if (const char *Name = MO.getTargetIndexName())
return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
stable_hash_combine_string(Name),
MO.getOffset());
StableHashBailingTargetIndexNoName++;
return 0;
}
case MachineOperand::MO_FrameIndex:
case MachineOperand::MO_JumpTableIndex:
return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
MO.getIndex());
case MachineOperand::MO_ExternalSymbol:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
stable_hash_combine_string(MO.getSymbolName()));
case MachineOperand::MO_RegisterMask:
case MachineOperand::MO_RegisterLiveOut:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
case MachineOperand::MO_ShuffleMask: {
std::vector<llvm::stable_hash> ShuffleMaskHashes;
llvm::transform(
MO.getShuffleMask(), std::back_inserter(ShuffleMaskHashes),
[](int S) -> llvm::stable_hash { return llvm::stable_hash(S); });
return hash_combine(MO.getType(), MO.getTargetFlags(),
stable_hash_combine_array(ShuffleMaskHashes.data(),
ShuffleMaskHashes.size()));
}
case MachineOperand::MO_MCSymbol: {
auto SymbolName = MO.getMCSymbol()->getName();
return hash_combine(MO.getType(), MO.getTargetFlags(),
stable_hash_combine_string(SymbolName));
}
case MachineOperand::MO_CFIIndex:
return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
MO.getCFIIndex());
case MachineOperand::MO_IntrinsicID:
return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
MO.getIntrinsicID());
case MachineOperand::MO_Predicate:
return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
MO.getPredicate());
}
llvm_unreachable("Invalid machine operand type");
}
/// A stable hash value for machine instructions.
/// Returns 0 if no stable hash could be computed.
/// The hashing and equality testing functions ignore definitions so this is
/// useful for CSE, etc.
stable_hash llvm::stableHashValue(const MachineInstr &MI, bool HashVRegs,
bool HashConstantPoolIndices,
bool HashMemOperands) {
// Build up a buffer of hash code components.
SmallVector<stable_hash, 16> HashComponents;
HashComponents.reserve(MI.getNumOperands() + MI.getNumMemOperands() + 2);
HashComponents.push_back(MI.getOpcode());
HashComponents.push_back(MI.getFlags());
for (const MachineOperand &MO : MI.operands()) {
if (!HashVRegs && MO.isReg() && MO.isDef() &&
Register::isVirtualRegister(MO.getReg()))
continue; // Skip virtual register defs.
if (MO.isCPI()) {
HashComponents.push_back(stable_hash_combine(
MO.getType(), MO.getTargetFlags(), MO.getIndex()));
continue;
}
stable_hash StableHash = stableHashValue(MO);
if (!StableHash)
return 0;
HashComponents.push_back(StableHash);
}
for (const auto *Op : MI.memoperands()) {
if (!HashMemOperands)
break;
HashComponents.push_back(static_cast<unsigned>(Op->getSize()));
HashComponents.push_back(static_cast<unsigned>(Op->getFlags()));
HashComponents.push_back(static_cast<unsigned>(Op->getOffset()));
HashComponents.push_back(static_cast<unsigned>(Op->getOrdering()));
HashComponents.push_back(static_cast<unsigned>(Op->getAddrSpace()));
HashComponents.push_back(static_cast<unsigned>(Op->getSyncScopeID()));
HashComponents.push_back(static_cast<unsigned>(Op->getBaseAlign().value()));
HashComponents.push_back(static_cast<unsigned>(Op->getFailureOrdering()));
}
return stable_hash_combine_range(HashComponents.begin(),
HashComponents.end());
}

View File

@@ -1,5 +1,6 @@
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass mir-canonicalizer -o - %s
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -verify-machineinstrs -o - %s | FileCheck %s
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass mir-canonicalizer -verify-machineinstrs -o - %s
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs -o - %s
--- |

View File

@@ -1,4 +1,5 @@
# RUN: llc -o - -run-pass mir-canonicalizer -verify-machineinstrs %s | FileCheck %s
# RUN: llc -o - -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs %s | FileCheck %s
--- |
target triple = "aarch64-unknown-unknown"
define void @f() { unreachable }

View File

@@ -1,4 +1,5 @@
# RUN: llc -run-pass mir-canonicalizer -verify-machineinstrs -mtriple aarch64-unknown-linux-gnu -o - %s | FileCheck %s
# RUN: llc -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs -mtriple aarch64-unknown-linux-gnu -o - %s | FileCheck %s
...
---
name: foo

View File

@@ -1,4 +1,5 @@
# RUN: llc -mtriple=arm64-apple-ios11.0.0 -o - -verify-machineinstrs -run-pass mir-canonicalizer %s | FileCheck %s
# RUN: llc -mtriple=arm64-apple-ios11.0.0 -o - -verify-machineinstrs -mir-vreg-namer-use-stable-hash -run-pass mir-canonicalizer %s | FileCheck %s
...
---

View File

@@ -1,4 +1,5 @@
# RUN: llc -mtriple=arm64-apple-ios11.0.0 -o - -verify-machineinstrs -run-pass mir-canonicalizer %s | FileCheck %s
# RUN: llc -mtriple=arm64-apple-ios11.0.0 -o - -mir-vreg-namer-use-stable-hash -verify-machineinstrs -run-pass mir-canonicalizer %s | FileCheck %s
# These Idempotent instructions are sorted alphabetically (based on after the '=')
# CHECK: %bb0_{{[0-9]+}}__1:gpr64 = MOVi64imm 4617315517961601024
# CHECK-NEXT: %bb0_{{[0-9]+}}__1:gpr32 = MOVi32imm 408

View File

@@ -1,4 +1,4 @@
# RUN: llc -x mir -mtriple aarch64-apple-ios -run-pass mir-namer -verify-machineinstrs -o - < %s | FileCheck %s
# RUN: llc -x mir -mtriple aarch64-apple-ios -run-pass mir-namer -mir-vreg-namer-use-stable-hash -verify-machineinstrs -o - < %s | FileCheck %s
---
name: foo

View File

@@ -1,4 +1,5 @@
# RUN: llc -o - -march=amdgcn -run-pass mir-canonicalizer %s | FileCheck %s
# RUN: llc -o - -march=amdgcn -run-pass mir-canonicalizer -verify-machineinstrs %s | FileCheck %s
# RUN: llc -o - -march=amdgcn -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs %s | FileCheck %s
# This tests for the itereator invalidation fix (reviews.llvm.org/D62713)
...

View File

@@ -1,4 +1,5 @@
# RUN: llc -march=amdgcn -mcpu=tahiti -run-pass mir-canonicalizer -o - %s | FileCheck %s
# RUN: llc -march=amdgcn -mcpu=tahiti -run-pass mir-canonicalizer -verify-machineinstrs -o - %s | FileCheck %s
# RUN: llc -march=amdgcn -mcpu=tahiti -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs -o - %s | FileCheck %s
--- |
target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"

View File

@@ -1,5 +1,6 @@
# RUN: llc -march=amdgcn -run-pass=none -verify-machineinstrs -o - %s | FileCheck %s
# RUN: llc -march=amdgcn -run-pass mir-canonicalizer -verify-machineinstrs -o - %s
# RUN: llc -march=amdgcn -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs -o - %s
# Previously getReservedRegs was called before parsing
# machineFunctionInfo, but the AMDGPU implementation depends on

View File

@@ -1,4 +1,5 @@
# RUN: llc -run-pass mir-canonicalizer -o - %s | FileCheck %s
# RUN: llc -run-pass mir-canonicalizer -verify-machineinstrs -o - %s | FileCheck %s
# RUN: llc -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs -o - %s | FileCheck %s
---
name: cimm_fpimm_hash_test
body: |

View File

@@ -1,5 +1,7 @@
# RUN: llc -run-pass mir-namer -x mir -verify-machineinstrs %s -o - | FileCheck %s
# RUN: llc -run-pass mir-canonicalizer -x mir -verify-machineinstrs %s -o - | FileCheck %s
# RUN: llc -run-pass mir-namer -mir-vreg-namer-use-stable-hash -x mir -verify-machineinstrs %s -o - | FileCheck %s
# RUN: llc -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -x mir -verify-machineinstrs %s -o - | FileCheck %s
--- |
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

View File

@@ -1,4 +1,5 @@
# RUN: llc -mtriple x86_64-linux-gnu -run-pass mir-canonicalizer -verify-machineinstrs %s -o - | FileCheck %s
# RUN: llc -mtriple x86_64-linux-gnu -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs %s -o - | FileCheck %s
...
---

View File

@@ -1,4 +1,5 @@
# RUN: llc -march=x86-64 -run-pass mir-canonicalizer -o - %s | FileCheck %s
# RUN: llc -march=x86-64 -run-pass mir-canonicalizer -verify-machineinstrs -o - %s | FileCheck %s
# RUN: llc -march=x86-64 -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs -o - %s | FileCheck %s
# The purpose of this test is to ensure that differing flags do in-fact cause
# naming collisions with the new vreg renamers naming scheme.
--- |