492 lines · cpp
1//===- Constant.cpp - The Constant classes of Sandbox IR ------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/SandboxIR/Constant.h"10#include "llvm/SandboxIR/BasicBlock.h"11#include "llvm/SandboxIR/Context.h"12#include "llvm/SandboxIR/Function.h"13#include "llvm/Support/Compiler.h"14 15namespace llvm::sandboxir {16 17#ifndef NDEBUG18void Constant::dumpOS(raw_ostream &OS) const {19 dumpCommonPrefix(OS);20 dumpCommonSuffix(OS);21}22#endif // NDEBUG23 24ConstantInt *ConstantInt::getTrue(Context &Ctx) {25 auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx);26 return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));27}28ConstantInt *ConstantInt::getFalse(Context &Ctx) {29 auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx);30 return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));31}32ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) {33 auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V);34 return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));35}36Constant *ConstantInt::getTrue(Type *Ty) {37 auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy);38 return Ty->getContext().getOrCreateConstant(LLVMC);39}40Constant *ConstantInt::getFalse(Type *Ty) {41 auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy);42 return Ty->getContext().getOrCreateConstant(LLVMC);43}44Constant *ConstantInt::getBool(Type *Ty, bool V) {45 auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V);46 return Ty->getContext().getOrCreateConstant(LLVMC);47}48ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) {49 auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);50 return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));51}52ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) {53 auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);54 return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));55}56ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {57 auto *LLVMC =58 llvm::ConstantInt::getSigned(cast<llvm::IntegerType>(Ty->LLVMTy), V);59 return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));60}61Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {62 auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V);63 return Ty->getContext().getOrCreateConstant(LLVMC);64}65ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) {66 auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V);67 return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));68}69ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) {70 auto *LLVMC =71 llvm::ConstantInt::get(cast<llvm::IntegerType>(Ty->LLVMTy), Str, Radix);72 return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));73}74Constant *ConstantInt::get(Type *Ty, const APInt &V) {75 auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V);76 return Ty->getContext().getOrCreateConstant(LLVMC);77}78IntegerType *ConstantInt::getIntegerType() const {79 auto *LLVMTy = cast<llvm::ConstantInt>(Val)->getIntegerType();80 return cast<IntegerType>(Ctx.getType(LLVMTy));81}82 83bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) {84 return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);85}86bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) {87 return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);88}89 90Constant *ConstantFP::get(Type *Ty, double V) {91 auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);92 return Ty->getContext().getOrCreateConstant(LLVMC);93}94 95Constant *ConstantFP::get(Type *Ty, const APFloat &V) {96 auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);97 return Ty->getContext().getOrCreateConstant(LLVMC);98}99 100Constant *ConstantFP::get(Type *Ty, StringRef Str) {101 auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, Str);102 return Ty->getContext().getOrCreateConstant(LLVMC);103}104 105ConstantFP *ConstantFP::get(const APFloat &V, Context &Ctx) {106 auto *LLVMC = llvm::ConstantFP::get(Ctx.LLVMCtx, V);107 return cast<ConstantFP>(Ctx.getOrCreateConstant(LLVMC));108}109 110Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {111 auto *LLVMC = llvm::ConstantFP::getNaN(Ty->LLVMTy, Negative, Payload);112 return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));113}114Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {115 auto *LLVMC = llvm::ConstantFP::getQNaN(Ty->LLVMTy, Negative, Payload);116 return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));117}118Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {119 auto *LLVMC = llvm::ConstantFP::getSNaN(Ty->LLVMTy, Negative, Payload);120 return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));121}122Constant *ConstantFP::getZero(Type *Ty, bool Negative) {123 auto *LLVMC = llvm::ConstantFP::getZero(Ty->LLVMTy, Negative);124 return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));125}126Constant *ConstantFP::getNegativeZero(Type *Ty) {127 auto *LLVMC = llvm::ConstantFP::getNegativeZero(Ty->LLVMTy);128 return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));129}130Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {131 auto *LLVMC = llvm::ConstantFP::getInfinity(Ty->LLVMTy, Negative);132 return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));133}134bool ConstantFP::isValueValidForType(Type *Ty, const APFloat &V) {135 return llvm::ConstantFP::isValueValidForType(Ty->LLVMTy, V);136}137 138Constant *ConstantArray::get(ArrayType *T, ArrayRef<Constant *> V) {139 auto &Ctx = T->getContext();140 SmallVector<llvm::Constant *> LLVMValues;141 LLVMValues.reserve(V.size());142 for (auto *Elm : V)143 LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));144 auto *LLVMC =145 llvm::ConstantArray::get(cast<llvm::ArrayType>(T->LLVMTy), LLVMValues);146 return cast<ConstantArray>(Ctx.getOrCreateConstant(LLVMC));147}148 149ArrayType *ConstantArray::getType() const {150 return cast<ArrayType>(151 Ctx.getType(cast<llvm::ConstantArray>(Val)->getType()));152}153 154Constant *ConstantStruct::get(StructType *T, ArrayRef<Constant *> V) {155 auto &Ctx = T->getContext();156 SmallVector<llvm::Constant *> LLVMValues;157 LLVMValues.reserve(V.size());158 for (auto *Elm : V)159 LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));160 auto *LLVMC =161 llvm::ConstantStruct::get(cast<llvm::StructType>(T->LLVMTy), LLVMValues);162 return cast<ConstantStruct>(Ctx.getOrCreateConstant(LLVMC));163}164 165StructType *ConstantStruct::getTypeForElements(Context &Ctx,166 ArrayRef<Constant *> V,167 bool Packed) {168 unsigned VecSize = V.size();169 SmallVector<Type *, 16> EltTypes;170 EltTypes.reserve(VecSize);171 for (Constant *Elm : V)172 EltTypes.push_back(Elm->getType());173 return StructType::get(Ctx, EltTypes, Packed);174}175 176Constant *ConstantVector::get(ArrayRef<Constant *> V) {177 assert(!V.empty() && "Expected non-empty V!");178 auto &Ctx = V[0]->getContext();179 SmallVector<llvm::Constant *, 8> LLVMV;180 LLVMV.reserve(V.size());181 for (auto *Elm : V)182 LLVMV.push_back(cast<llvm::Constant>(Elm->Val));183 return Ctx.getOrCreateConstant(llvm::ConstantVector::get(LLVMV));184}185 186Constant *ConstantVector::getSplat(ElementCount EC, Constant *Elt) {187 auto *LLVMElt = cast<llvm::Constant>(Elt->Val);188 auto &Ctx = Elt->getContext();189 return Ctx.getOrCreateConstant(llvm::ConstantVector::getSplat(EC, LLVMElt));190}191 192Constant *ConstantVector::getSplatValue(bool AllowPoison) const {193 auto *LLVMSplatValue = cast_or_null<llvm::Constant>(194 cast<llvm::ConstantVector>(Val)->getSplatValue(AllowPoison));195 return LLVMSplatValue ? Ctx.getOrCreateConstant(LLVMSplatValue) : nullptr;196}197 198ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {199 auto *LLVMC = llvm::ConstantAggregateZero::get(Ty->LLVMTy);200 return cast<ConstantAggregateZero>(201 Ty->getContext().getOrCreateConstant(LLVMC));202}203 204Constant *ConstantAggregateZero::getSequentialElement() const {205 return cast<Constant>(Ctx.getValue(206 cast<llvm::ConstantAggregateZero>(Val)->getSequentialElement()));207}208Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {209 return cast<Constant>(Ctx.getValue(210 cast<llvm::ConstantAggregateZero>(Val)->getStructElement(Elt)));211}212Constant *ConstantAggregateZero::getElementValue(Constant *C) const {213 return cast<Constant>(214 Ctx.getValue(cast<llvm::ConstantAggregateZero>(Val)->getElementValue(215 cast<llvm::Constant>(C->Val))));216}217Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {218 return cast<Constant>(Ctx.getValue(219 cast<llvm::ConstantAggregateZero>(Val)->getElementValue(Idx)));220}221 222ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {223 auto *LLVMC =224 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty->LLVMTy));225 return cast<ConstantPointerNull>(Ty->getContext().getOrCreateConstant(LLVMC));226}227 228PointerType *ConstantPointerNull::getType() const {229 return cast<PointerType>(230 Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getType()));231}232 233UndefValue *UndefValue::get(Type *T) {234 auto *LLVMC = llvm::UndefValue::get(T->LLVMTy);235 return cast<UndefValue>(T->getContext().getOrCreateConstant(LLVMC));236}237 238UndefValue *UndefValue::getSequentialElement() const {239 return cast<UndefValue>(Ctx.getOrCreateConstant(240 cast<llvm::UndefValue>(Val)->getSequentialElement()));241}242 243UndefValue *UndefValue::getStructElement(unsigned Elt) const {244 return cast<UndefValue>(Ctx.getOrCreateConstant(245 cast<llvm::UndefValue>(Val)->getStructElement(Elt)));246}247 248UndefValue *UndefValue::getElementValue(Constant *C) const {249 return cast<UndefValue>(250 Ctx.getOrCreateConstant(cast<llvm::UndefValue>(Val)->getElementValue(251 cast<llvm::Constant>(C->Val))));252}253 254UndefValue *UndefValue::getElementValue(unsigned Idx) const {255 return cast<UndefValue>(Ctx.getOrCreateConstant(256 cast<llvm::UndefValue>(Val)->getElementValue(Idx)));257}258 259PoisonValue *PoisonValue::get(Type *T) {260 auto *LLVMC = llvm::PoisonValue::get(T->LLVMTy);261 return cast<PoisonValue>(T->getContext().getOrCreateConstant(LLVMC));262}263 264PoisonValue *PoisonValue::getSequentialElement() const {265 return cast<PoisonValue>(Ctx.getOrCreateConstant(266 cast<llvm::PoisonValue>(Val)->getSequentialElement()));267}268 269PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {270 return cast<PoisonValue>(Ctx.getOrCreateConstant(271 cast<llvm::PoisonValue>(Val)->getStructElement(Elt)));272}273 274PoisonValue *PoisonValue::getElementValue(Constant *C) const {275 return cast<PoisonValue>(276 Ctx.getOrCreateConstant(cast<llvm::PoisonValue>(Val)->getElementValue(277 cast<llvm::Constant>(C->Val))));278}279 280PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {281 return cast<PoisonValue>(Ctx.getOrCreateConstant(282 cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));283}284 285void GlobalVariable::setAlignment(MaybeAlign Align) {286 Ctx.getTracker()287 .emplaceIfTracking<GenericSetter<&GlobalVariable::getAlign,288 &GlobalVariable::setAlignment>>(this);289 cast<llvm::GlobalVariable>(Val)->setAlignment(Align);290}291 292void GlobalObject::setSection(StringRef S) {293 Ctx.getTracker()294 .emplaceIfTracking<295 GenericSetter<&GlobalObject::getSection, &GlobalObject::setSection>>(296 this);297 cast<llvm::GlobalObject>(Val)->setSection(S);298}299 300template <typename GlobalT, typename LLVMGlobalT, typename ParentT,301 typename LLVMParentT>302GlobalT &GlobalWithNodeAPI<GlobalT, LLVMGlobalT, ParentT, LLVMParentT>::303 LLVMGVToGV::operator()(LLVMGlobalT &LLVMGV) const {304 return cast<GlobalT>(*Ctx.getValue(&LLVMGV));305}306 307// Explicit instantiations.308template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<309 GlobalIFunc, llvm::GlobalIFunc, GlobalObject, llvm::GlobalObject>;310template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<311 Function, llvm::Function, GlobalObject, llvm::GlobalObject>;312template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<313 GlobalVariable, llvm::GlobalVariable, GlobalObject, llvm::GlobalObject>;314template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<315 GlobalAlias, llvm::GlobalAlias, GlobalValue, llvm::GlobalValue>;316 317void GlobalIFunc::setResolver(Constant *Resolver) {318 Ctx.getTracker()319 .emplaceIfTracking<320 GenericSetter<&GlobalIFunc::getResolver, &GlobalIFunc::setResolver>>(321 this);322 cast<llvm::GlobalIFunc>(Val)->setResolver(323 cast<llvm::Constant>(Resolver->Val));324}325 326Constant *GlobalIFunc::getResolver() const {327 return Ctx.getOrCreateConstant(cast<llvm::GlobalIFunc>(Val)->getResolver());328}329 330Function *GlobalIFunc::getResolverFunction() {331 return cast<Function>(Ctx.getOrCreateConstant(332 cast<llvm::GlobalIFunc>(Val)->getResolverFunction()));333}334 335GlobalVariable &336GlobalVariable::LLVMGVToGV::operator()(llvm::GlobalVariable &LLVMGV) const {337 return cast<GlobalVariable>(*Ctx.getValue(&LLVMGV));338}339 340Constant *GlobalVariable::getInitializer() const {341 return Ctx.getOrCreateConstant(342 cast<llvm::GlobalVariable>(Val)->getInitializer());343}344 345void GlobalVariable::setInitializer(Constant *InitVal) {346 Ctx.getTracker()347 .emplaceIfTracking<GenericSetter<&GlobalVariable::getInitializer,348 &GlobalVariable::setInitializer>>(this);349 cast<llvm::GlobalVariable>(Val)->setInitializer(350 cast<llvm::Constant>(InitVal->Val));351}352 353void GlobalVariable::setConstant(bool V) {354 Ctx.getTracker()355 .emplaceIfTracking<GenericSetter<&GlobalVariable::isConstant,356 &GlobalVariable::setConstant>>(this);357 cast<llvm::GlobalVariable>(Val)->setConstant(V);358}359 360void GlobalVariable::setExternallyInitialized(bool V) {361 Ctx.getTracker()362 .emplaceIfTracking<363 GenericSetter<&GlobalVariable::isExternallyInitialized,364 &GlobalVariable::setExternallyInitialized>>(this);365 cast<llvm::GlobalVariable>(Val)->setExternallyInitialized(V);366}367 368void GlobalAlias::setAliasee(Constant *Aliasee) {369 Ctx.getTracker()370 .emplaceIfTracking<371 GenericSetter<&GlobalAlias::getAliasee, &GlobalAlias::setAliasee>>(372 this);373 cast<llvm::GlobalAlias>(Val)->setAliasee(cast<llvm::Constant>(Aliasee->Val));374}375 376Constant *GlobalAlias::getAliasee() const {377 return cast<Constant>(378 Ctx.getOrCreateConstant(cast<llvm::GlobalAlias>(Val)->getAliasee()));379}380 381const GlobalObject *GlobalAlias::getAliaseeObject() const {382 return cast<GlobalObject>(Ctx.getOrCreateConstant(383 cast<llvm::GlobalAlias>(Val)->getAliaseeObject()));384}385 386void GlobalValue::setUnnamedAddr(UnnamedAddr V) {387 Ctx.getTracker()388 .emplaceIfTracking<GenericSetter<&GlobalValue::getUnnamedAddr,389 &GlobalValue::setUnnamedAddr>>(this);390 cast<llvm::GlobalValue>(Val)->setUnnamedAddr(V);391}392 393void GlobalValue::setVisibility(VisibilityTypes V) {394 Ctx.getTracker()395 .emplaceIfTracking<GenericSetter<&GlobalValue::getVisibility,396 &GlobalValue::setVisibility>>(this);397 cast<llvm::GlobalValue>(Val)->setVisibility(V);398}399 400NoCFIValue *NoCFIValue::get(GlobalValue *GV) {401 auto *LLVMC = llvm::NoCFIValue::get(cast<llvm::GlobalValue>(GV->Val));402 return cast<NoCFIValue>(GV->getContext().getOrCreateConstant(LLVMC));403}404 405GlobalValue *NoCFIValue::getGlobalValue() const {406 auto *LLVMC = cast<llvm::NoCFIValue>(Val)->getGlobalValue();407 return cast<GlobalValue>(Ctx.getOrCreateConstant(LLVMC));408}409 410PointerType *NoCFIValue::getType() const {411 return cast<PointerType>(Ctx.getType(cast<llvm::NoCFIValue>(Val)->getType()));412}413 414ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,415 ConstantInt *Disc, Constant *AddrDisc,416 Constant *DeactivationSymbol) {417 auto *LLVMC = llvm::ConstantPtrAuth::get(418 cast<llvm::Constant>(Ptr->Val), cast<llvm::ConstantInt>(Key->Val),419 cast<llvm::ConstantInt>(Disc->Val), cast<llvm::Constant>(AddrDisc->Val),420 cast<llvm::Constant>(DeactivationSymbol->Val));421 return cast<ConstantPtrAuth>(Ptr->getContext().getOrCreateConstant(LLVMC));422}423 424Constant *ConstantPtrAuth::getPointer() const {425 return Ctx.getOrCreateConstant(426 cast<llvm::ConstantPtrAuth>(Val)->getPointer());427}428 429ConstantInt *ConstantPtrAuth::getKey() const {430 return cast<ConstantInt>(431 Ctx.getOrCreateConstant(cast<llvm::ConstantPtrAuth>(Val)->getKey()));432}433 434ConstantInt *ConstantPtrAuth::getDiscriminator() const {435 return cast<ConstantInt>(Ctx.getOrCreateConstant(436 cast<llvm::ConstantPtrAuth>(Val)->getDiscriminator()));437}438 439Constant *ConstantPtrAuth::getAddrDiscriminator() const {440 return Ctx.getOrCreateConstant(441 cast<llvm::ConstantPtrAuth>(Val)->getAddrDiscriminator());442}443 444Constant *ConstantPtrAuth::getDeactivationSymbol() const {445 return Ctx.getOrCreateConstant(446 cast<llvm::ConstantPtrAuth>(Val)->getDeactivationSymbol());447}448 449ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {450 auto *LLVMC = cast<llvm::ConstantPtrAuth>(Val)->getWithSameSchema(451 cast<llvm::Constant>(Pointer->Val));452 return cast<ConstantPtrAuth>(Ctx.getOrCreateConstant(LLVMC));453}454 455BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {456 auto *LLVMC = llvm::BlockAddress::get(cast<llvm::Function>(F->Val),457 cast<llvm::BasicBlock>(BB->Val));458 return cast<BlockAddress>(F->getContext().getOrCreateConstant(LLVMC));459}460 461BlockAddress *BlockAddress::get(BasicBlock *BB) {462 auto *LLVMC = llvm::BlockAddress::get(cast<llvm::BasicBlock>(BB->Val));463 return cast<BlockAddress>(BB->getContext().getOrCreateConstant(LLVMC));464}465 466BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {467 auto *LLVMC = llvm::BlockAddress::lookup(cast<llvm::BasicBlock>(BB->Val));468 return cast_or_null<BlockAddress>(BB->getContext().getValue(LLVMC));469}470 471Function *BlockAddress::getFunction() const {472 return cast<Function>(473 Ctx.getValue(cast<llvm::BlockAddress>(Val)->getFunction()));474}475 476BasicBlock *BlockAddress::getBasicBlock() const {477 return cast<BasicBlock>(478 Ctx.getValue(cast<llvm::BlockAddress>(Val)->getBasicBlock()));479}480 481DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {482 auto *LLVMC = llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(GV->Val));483 return cast<DSOLocalEquivalent>(GV->getContext().getValue(LLVMC));484}485 486GlobalValue *DSOLocalEquivalent::getGlobalValue() const {487 return cast<GlobalValue>(488 Ctx.getValue(cast<llvm::DSOLocalEquivalent>(Val)->getGlobalValue()));489}490 491} // namespace llvm::sandboxir492