/
redgpu
/
clspv
Обзор
Документация
Войти
/
redgpu
/
clspv
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
lib/ConstantEmitter.cpp
143 строки
4 KB
James Price
Update LLVM (#737)
12 май 2021, 15:08
Не верифицирован
12 май 2021, 15:08
7eb6025
Код
Авторство
О чём код?
// Copyright 2018 The Clspv Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "ConstantEmitter.h" #include <cassert> #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Value.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; namespace clspv { void ConstantEmitter::Emit(Constant *c) { AlignTo(Layout.getABITypeAlignment(c->getType())); if (auto i = dyn_cast<ConstantInt>(c)) { EmitInt(i); } else if (auto f = dyn_cast<ConstantFP>(c)) { EmitFP(f); } else if (auto st = dyn_cast<ConstantStruct>(c)) { EmitStruct(st); } else if (auto ag = dyn_cast<ConstantArray>(c)) { EmitAggregate(ag); } else if (auto ag = dyn_cast<ConstantVector>(c)) { EmitAggregate(ag); } else if (auto cds = dyn_cast<ConstantDataSequential>(c)) { EmitDataSequential(cds); } else if (auto ag = dyn_cast<ConstantAggregate>(c)) { EmitAggregate(ag); } else if (auto ag = dyn_cast<ConstantAggregateZero>(c)) { EmitAggregateZero(ag); } else { errs() << "Don't know how to emit " << *c << " with value id " << int(c->getValueID()) << " compared to " << int(Value::ConstantVectorVal) << "\n"; llvm_unreachable("Unhandled constant"); } } void ConstantEmitter::EmitZeroes(size_t n) { for (size_t i = 0; i < n; ++i) { Out << "00"; ++Offset; } } void ConstantEmitter::AlignTo(size_t alignment) { size_t overflow = Offset % alignment; if (overflow) { const size_t padding = alignment - overflow; EmitZeroes(padding); } assert(0 == (Offset % alignment)); } void ConstantEmitter::EmitStruct(ConstantStruct *c) { const StructLayout *sl = Layout.getStructLayout(c->getType()); AlignTo(sl->getAlignment().value()); // Might be redundant. const size_t BaseOffset = Offset; for (unsigned i = 0; i < c->getNumOperands(); ++i) { EmitZeroes(sl->getElementOffset(i) - (Offset - BaseOffset)); Emit(c->getOperand(i)); } EmitZeroes(sl->getSizeInBytes() - (Offset - BaseOffset)); } void ConstantEmitter::EmitDataSequential(ConstantDataSequential *c) { for (unsigned i = 0; i < c->getNumElements(); ++i) { // The elements will align themselves. Constant *elem = c->getElementAsConstant(i); Emit(elem); } } void ConstantEmitter::EmitAggregate(ConstantAggregate *c) { for (unsigned i = 0; i < c->getNumOperands(); ++i) { // The elements will align themselves. Emit(c->getOperand(i)); } } void ConstantEmitter::EmitAggregateZero(ConstantAggregateZero *c) { if (StructType *sty = dyn_cast<StructType>(c->getType())) { const StructLayout *sl = Layout.getStructLayout(sty); AlignTo(sl->getAlignment().value()); // Might be redundant. const size_t BaseOffset = Offset; for (unsigned i = 0; i < c->getElementCount().getFixedValue(); ++i) { EmitZeroes(sl->getElementOffset(i) - (Offset - BaseOffset)); Emit(c->getElementValue(i)); } EmitZeroes(sl->getSizeInBytes() - (Offset - BaseOffset)); } else { for (unsigned i = 0; i < c->getElementCount().getFixedValue(); ++i) { // The elements will align themselves. Emit(c->getElementValue(i)); } } } void ConstantEmitter::EmitInt(ConstantInt *c) { EmitRaw(c->getBitWidth(), c->getValue().getRawData()); } void ConstantEmitter::EmitFP(ConstantFP *c) { APInt asInt = c->getValueAPF().bitcastToAPInt(); EmitRaw(asInt.getBitWidth(), asInt.getRawData()); } void ConstantEmitter::EmitRaw(unsigned num_bits, const uint64_t *data) { unsigned num_bytes = (num_bits + 7) / 8; while (num_bytes) { uint64_t word = *data++; for (int i = 0; i < 8 && num_bytes; --num_bytes, ++i) { EmitByte(word & 0xff); word = (word >> 8); } } } void ConstantEmitter::EmitByte(size_t byte) { static const char hex[] = "0123456789abcdef"; Out << hex[(byte & 0xf0) >> 4] << hex[byte & 0xf]; ++Offset; } } // namespace clspv