diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp')
-rw-r--r-- | contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp b/contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp new file mode 100644 index 0000000000..d2f676192e --- /dev/null +++ b/contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp @@ -0,0 +1,135 @@ +//===- ReplaceConstant.cpp - Replace LLVM constant expression--------------===// +// +// 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 implements a utility function for replacing LLVM constant +// expressions by instructions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/ReplaceConstant.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/ValueMap.h" + +namespace llvm { + +void convertConstantExprsToInstructions(Instruction *I, ConstantExpr *CE, + SmallPtrSetImpl<Instruction *> *Insts) { + // Collect all reachable paths to CE from constant exprssion operands of I. + std::map<Use *, std::vector<std::vector<ConstantExpr *>>> CEPaths; + collectConstantExprPaths(I, CE, CEPaths); + + // Convert all constant expressions to instructions which are collected at + // CEPaths. + convertConstantExprsToInstructions(I, CEPaths, Insts); +} + +void convertConstantExprsToInstructions( + Instruction *I, + std::map<Use *, std::vector<std::vector<ConstantExpr *>>> &CEPaths, + SmallPtrSetImpl<Instruction *> *Insts) { + ValueMap<ConstantExpr *, Instruction *> Visited; + + for (Use &U : I->operands()) { + // The operand U is either not a constant expression operand or the + // constant expression paths do not belong to U, ignore U. + if (!CEPaths.count(&U)) + continue; + + // If the instruction I is a PHI instruction, then fix the instruction + // insertion point to the entry of the incoming basic block for operand U. + auto *BI = I; + if (auto *Phi = dyn_cast<PHINode>(I)) { + BasicBlock *BB = Phi->getIncomingBlock(U); + BI = &(*(BB->getFirstInsertionPt())); + } + + // Go through all the paths associated with operand U, and convert all the + // constant expressions along all the paths to corresponding instructions. + auto *II = I; + auto &Paths = CEPaths[&U]; + for (auto &Path : Paths) { + for (auto *CE : Path) { + // Instruction which is equivalent to CE. + Instruction *NI = nullptr; + + if (!Visited.count(CE)) { + // CE is encountered first time, convert it into a corresponding + // instruction NI, and appropriately insert NI before the parent + // instruction. + NI = CE->getAsInstruction(BI); + + // Mark CE as visited by mapping CE to NI. + Visited[CE] = NI; + + // If required collect NI. + if (Insts) + Insts->insert(NI); + } else { + // We had already encountered CE, the correponding instruction already + // exist, use it to replace CE. + NI = Visited[CE]; + } + + assert(NI && "Expected an instruction corresponding to constant " + "expression."); + + // Replace all uses of constant expression CE by the corresponding + // instruction NI within the current parent instruction. + II->replaceUsesOfWith(CE, NI); + BI = II = NI; + } + } + } + + // Remove all converted constant expressions which are dead by now. + for (auto Item : Visited) + Item.first->removeDeadConstantUsers(); +} + +void collectConstantExprPaths( + Instruction *I, ConstantExpr *CE, + std::map<Use *, std::vector<std::vector<ConstantExpr *>>> &CEPaths) { + for (Use &U : I->operands()) { + // If the operand U is not a constant expression operand, then ignore it. + auto *CE2 = dyn_cast<ConstantExpr>(U.get()); + if (!CE2) + continue; + + // Holds all reachable paths from CE2 to CE. + std::vector<std::vector<ConstantExpr *>> Paths; + + // Collect all reachable paths from CE2 to CE. + std::vector<ConstantExpr *> Path{CE2}; + std::vector<std::vector<ConstantExpr *>> Stack{Path}; + while (!Stack.empty()) { + std::vector<ConstantExpr *> TPath = Stack.back(); + Stack.pop_back(); + auto *CE3 = TPath.back(); + + if (CE3 == CE) { + Paths.push_back(TPath); + continue; + } + + for (auto &UU : CE3->operands()) { + if (auto *CE4 = dyn_cast<ConstantExpr>(UU.get())) { + std::vector<ConstantExpr *> NPath(TPath.begin(), TPath.end()); + NPath.push_back(CE4); + Stack.push_back(NPath); + } + } + } + + // Associate all the collected paths with U, and save it. + if (!Paths.empty()) + CEPaths[&U] = Paths; + } +} + +} // namespace llvm |