mkql_reverse.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include "mkql_reverse.h"
  2. #include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
  3. #include <yql/essentials/minikql/computation/mkql_computation_node_codegen.h> // Y_IGNORE
  4. #include <yql/essentials/minikql/mkql_node_cast.h>
  5. namespace NKikimr {
  6. namespace NMiniKQL {
  7. namespace {
  8. class TReverseWrapper : public TMutableCodegeneratorNode<TReverseWrapper> {
  9. typedef TMutableCodegeneratorNode<TReverseWrapper> TBaseComputation;
  10. public:
  11. TReverseWrapper(TComputationMutables& mutables, IComputationNode* list)
  12. : TBaseComputation(mutables, list->GetRepresentation())
  13. , List(list)
  14. {
  15. }
  16. NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
  17. return ctx.HolderFactory.ReverseList(ctx.Builder, List->GetValue(ctx).Release());
  18. }
  19. #ifndef MKQL_DISABLE_CODEGEN
  20. Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
  21. auto& context = ctx.Codegen.GetContext();
  22. const auto indexType = Type::getInt32Ty(context);
  23. const auto first = GetElementPtrInst::CreateInBounds(GetCompContextType(context), ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "first", block);
  24. const auto fourth = GetElementPtrInst::CreateInBounds(GetCompContextType(context), ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "fourth", block);
  25. const auto structPtrType = PointerType::getUnqual(StructType::get(context));
  26. const auto factory = new LoadInst(structPtrType, first, "factory", block);
  27. const auto builder = new LoadInst(structPtrType, fourth, "builder", block);
  28. const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::ReverseList));
  29. const auto list = GetNodeValue(List, ctx, block);
  30. if (NYql::NCodegen::ETarget::Windows != ctx.Codegen.GetEffectiveTarget()) {
  31. const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType()}, false);
  32. const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
  33. const auto result = CallInst::Create(funType, funcPtr, {factory, builder, list}, "result", block);
  34. return result;
  35. } else {
  36. const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
  37. new StoreInst(list, retPtr, block);
  38. const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType()}, false);
  39. const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
  40. CallInst::Create(funType, funcPtr, {factory, retPtr, builder, retPtr}, "", block);
  41. const auto result = new LoadInst(list->getType(), retPtr, "result", block);
  42. return result;
  43. }
  44. }
  45. #endif
  46. private:
  47. void RegisterDependencies() const final {
  48. DependsOn(List);
  49. }
  50. IComputationNode* const List;
  51. };
  52. }
  53. IComputationNode* WrapReverse(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
  54. MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
  55. return new TReverseWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
  56. }
  57. }
  58. }