//===- Constant.cpp - The Constant classes of Sandbox IR ------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "llvm/SandboxIR/Constant.h" #include "llvm/SandboxIR/Argument.h" #include "llvm/SandboxIR/BasicBlock.h" #include "llvm/SandboxIR/Context.h" #include "llvm/SandboxIR/Function.h" #include "llvm/Support/Compiler.h" namespace llvm::sandboxir { #ifndef NDEBUG void Constant::dumpOS(raw_ostream &OS) const { dumpCommonPrefix(OS); dumpCommonSuffix(OS); } #endif // NDEBUG ConstantInt *ConstantInt::getTrue(Context &Ctx) { auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx); return cast(Ctx.getOrCreateConstant(LLVMC)); } ConstantInt *ConstantInt::getFalse(Context &Ctx) { auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx); return cast(Ctx.getOrCreateConstant(LLVMC)); } ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) { auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V); return cast(Ctx.getOrCreateConstant(LLVMC)); } Constant *ConstantInt::getTrue(Type *Ty) { auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy); return Ty->getContext().getOrCreateConstant(LLVMC); } Constant *ConstantInt::getFalse(Type *Ty) { auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy); return Ty->getContext().getOrCreateConstant(LLVMC); } Constant *ConstantInt::getBool(Type *Ty, bool V) { auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V); return Ty->getContext().getOrCreateConstant(LLVMC); } ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) { auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) { auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) { auto *LLVMC = llvm::ConstantInt::getSigned(cast(Ty->LLVMTy), V); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantInt::getSigned(Type *Ty, int64_t V) { auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V); return Ty->getContext().getOrCreateConstant(LLVMC); } ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) { auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V); return cast(Ctx.getOrCreateConstant(LLVMC)); } ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) { auto *LLVMC = llvm::ConstantInt::get(cast(Ty->LLVMTy), Str, Radix); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantInt::get(Type *Ty, const APInt &V) { auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V); return Ty->getContext().getOrCreateConstant(LLVMC); } IntegerType *ConstantInt::getIntegerType() const { auto *LLVMTy = cast(Val)->getIntegerType(); return cast(Ctx.getType(LLVMTy)); } bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) { return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V); } bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) { return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V); } Constant *ConstantFP::get(Type *Ty, double V) { auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V); return Ty->getContext().getOrCreateConstant(LLVMC); } Constant *ConstantFP::get(Type *Ty, const APFloat &V) { auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V); return Ty->getContext().getOrCreateConstant(LLVMC); } Constant *ConstantFP::get(Type *Ty, StringRef Str) { auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, Str); return Ty->getContext().getOrCreateConstant(LLVMC); } ConstantFP *ConstantFP::get(const APFloat &V, Context &Ctx) { auto *LLVMC = llvm::ConstantFP::get(Ctx.LLVMCtx, V); return cast(Ctx.getOrCreateConstant(LLVMC)); } Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) { auto *LLVMC = llvm::ConstantFP::getNaN(Ty->LLVMTy, Negative, Payload); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) { auto *LLVMC = llvm::ConstantFP::getQNaN(Ty->LLVMTy, Negative, Payload); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) { auto *LLVMC = llvm::ConstantFP::getSNaN(Ty->LLVMTy, Negative, Payload); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantFP::getZero(Type *Ty, bool Negative) { auto *LLVMC = llvm::ConstantFP::getZero(Ty->LLVMTy, Negative); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantFP::getNegativeZero(Type *Ty) { auto *LLVMC = llvm::ConstantFP::getNegativeZero(Ty->LLVMTy); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) { auto *LLVMC = llvm::ConstantFP::getInfinity(Ty->LLVMTy, Negative); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } bool ConstantFP::isValueValidForType(Type *Ty, const APFloat &V) { return llvm::ConstantFP::isValueValidForType(Ty->LLVMTy, V); } Constant *ConstantArray::get(ArrayType *T, ArrayRef V) { auto &Ctx = T->getContext(); SmallVector LLVMValues; LLVMValues.reserve(V.size()); for (auto *Elm : V) LLVMValues.push_back(cast(Elm->Val)); auto *LLVMC = llvm::ConstantArray::get(cast(T->LLVMTy), LLVMValues); return cast(Ctx.getOrCreateConstant(LLVMC)); } ArrayType *ConstantArray::getType() const { return cast( Ctx.getType(cast(Val)->getType())); } Constant *ConstantStruct::get(StructType *T, ArrayRef V) { auto &Ctx = T->getContext(); SmallVector LLVMValues; LLVMValues.reserve(V.size()); for (auto *Elm : V) LLVMValues.push_back(cast(Elm->Val)); auto *LLVMC = llvm::ConstantStruct::get(cast(T->LLVMTy), LLVMValues); return cast(Ctx.getOrCreateConstant(LLVMC)); } StructType *ConstantStruct::getTypeForElements(Context &Ctx, ArrayRef V, bool Packed) { unsigned VecSize = V.size(); SmallVector EltTypes; EltTypes.reserve(VecSize); for (Constant *Elm : V) EltTypes.push_back(Elm->getType()); return StructType::get(Ctx, EltTypes, Packed); } ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) { auto *LLVMC = llvm::ConstantAggregateZero::get(Ty->LLVMTy); return cast( Ty->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantAggregateZero::getSequentialElement() const { return cast(Ctx.getValue( cast(Val)->getSequentialElement())); } Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const { return cast(Ctx.getValue( cast(Val)->getStructElement(Elt))); } Constant *ConstantAggregateZero::getElementValue(Constant *C) const { return cast( Ctx.getValue(cast(Val)->getElementValue( cast(C->Val)))); } Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const { return cast(Ctx.getValue( cast(Val)->getElementValue(Idx))); } ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) { auto *LLVMC = llvm::ConstantPointerNull::get(cast(Ty->LLVMTy)); return cast(Ty->getContext().getOrCreateConstant(LLVMC)); } PointerType *ConstantPointerNull::getType() const { return cast( Ctx.getType(cast(Val)->getType())); } UndefValue *UndefValue::get(Type *T) { auto *LLVMC = llvm::UndefValue::get(T->LLVMTy); return cast(T->getContext().getOrCreateConstant(LLVMC)); } UndefValue *UndefValue::getSequentialElement() const { return cast(Ctx.getOrCreateConstant( cast(Val)->getSequentialElement())); } UndefValue *UndefValue::getStructElement(unsigned Elt) const { return cast(Ctx.getOrCreateConstant( cast(Val)->getStructElement(Elt))); } UndefValue *UndefValue::getElementValue(Constant *C) const { return cast( Ctx.getOrCreateConstant(cast(Val)->getElementValue( cast(C->Val)))); } UndefValue *UndefValue::getElementValue(unsigned Idx) const { return cast(Ctx.getOrCreateConstant( cast(Val)->getElementValue(Idx))); } PoisonValue *PoisonValue::get(Type *T) { auto *LLVMC = llvm::PoisonValue::get(T->LLVMTy); return cast(T->getContext().getOrCreateConstant(LLVMC)); } PoisonValue *PoisonValue::getSequentialElement() const { return cast(Ctx.getOrCreateConstant( cast(Val)->getSequentialElement())); } PoisonValue *PoisonValue::getStructElement(unsigned Elt) const { return cast(Ctx.getOrCreateConstant( cast(Val)->getStructElement(Elt))); } PoisonValue *PoisonValue::getElementValue(Constant *C) const { return cast( Ctx.getOrCreateConstant(cast(Val)->getElementValue( cast(C->Val)))); } PoisonValue *PoisonValue::getElementValue(unsigned Idx) const { return cast(Ctx.getOrCreateConstant( cast(Val)->getElementValue(Idx))); } void GlobalObject::setAlignment(MaybeAlign Align) { Ctx.getTracker() .emplaceIfTracking< GenericSetter<&GlobalObject::getAlign, &GlobalObject::setAlignment>>( this); cast(Val)->setAlignment(Align); } void GlobalObject::setGlobalObjectSubClassData(unsigned V) { Ctx.getTracker() .emplaceIfTracking< GenericSetter<&GlobalObject::getGlobalObjectSubClassData, &GlobalObject::setGlobalObjectSubClassData>>(this); cast(Val)->setGlobalObjectSubClassData(V); } void GlobalObject::setSection(StringRef S) { Ctx.getTracker() .emplaceIfTracking< GenericSetter<&GlobalObject::getSection, &GlobalObject::setSection>>( this); cast(Val)->setSection(S); } template GlobalT &GlobalWithNodeAPI:: LLVMGVToGV::operator()(LLVMGlobalT &LLVMGV) const { return cast(*Ctx.getValue(&LLVMGV)); } // Explicit instantiations. template class GlobalWithNodeAPI; template class GlobalWithNodeAPI; template class GlobalWithNodeAPI; template class GlobalWithNodeAPI; #ifdef _MSC_VER // These are needed for SandboxIRTest when building with LLVM_BUILD_LLVM_DYLIB template LLVM_EXPORT_TEMPLATE GlobalIFunc & GlobalWithNodeAPI::LLVMGVToGV::operator()(llvm::GlobalIFunc &LLVMGV) const; template LLVM_EXPORT_TEMPLATE Function & GlobalWithNodeAPI:: LLVMGVToGV::operator()(llvm::Function &LLVMGV) const; template LLVM_EXPORT_TEMPLATE GlobalVariable &GlobalWithNodeAPI< GlobalVariable, llvm::GlobalVariable, GlobalObject, llvm::GlobalObject>::LLVMGVToGV::operator()(llvm::GlobalVariable &LLVMGV) const; template LLVM_EXPORT_TEMPLATE GlobalAlias & GlobalWithNodeAPI::LLVMGVToGV::operator()(llvm::GlobalAlias &LLVMGV) const; #endif void GlobalIFunc::setResolver(Constant *Resolver) { Ctx.getTracker() .emplaceIfTracking< GenericSetter<&GlobalIFunc::getResolver, &GlobalIFunc::setResolver>>( this); cast(Val)->setResolver( cast(Resolver->Val)); } Constant *GlobalIFunc::getResolver() const { return Ctx.getOrCreateConstant(cast(Val)->getResolver()); } Function *GlobalIFunc::getResolverFunction() { return cast(Ctx.getOrCreateConstant( cast(Val)->getResolverFunction())); } GlobalVariable & GlobalVariable::LLVMGVToGV::operator()(llvm::GlobalVariable &LLVMGV) const { return cast(*Ctx.getValue(&LLVMGV)); } Constant *GlobalVariable::getInitializer() const { return Ctx.getOrCreateConstant( cast(Val)->getInitializer()); } void GlobalVariable::setInitializer(Constant *InitVal) { Ctx.getTracker() .emplaceIfTracking>(this); cast(Val)->setInitializer( cast(InitVal->Val)); } void GlobalVariable::setConstant(bool V) { Ctx.getTracker() .emplaceIfTracking>(this); cast(Val)->setConstant(V); } void GlobalVariable::setExternallyInitialized(bool V) { Ctx.getTracker() .emplaceIfTracking< GenericSetter<&GlobalVariable::isExternallyInitialized, &GlobalVariable::setExternallyInitialized>>(this); cast(Val)->setExternallyInitialized(V); } void GlobalAlias::setAliasee(Constant *Aliasee) { Ctx.getTracker() .emplaceIfTracking< GenericSetter<&GlobalAlias::getAliasee, &GlobalAlias::setAliasee>>( this); cast(Val)->setAliasee(cast(Aliasee->Val)); } Constant *GlobalAlias::getAliasee() const { return cast( Ctx.getOrCreateConstant(cast(Val)->getAliasee())); } const GlobalObject *GlobalAlias::getAliaseeObject() const { return cast(Ctx.getOrCreateConstant( cast(Val)->getAliaseeObject())); } void GlobalValue::setUnnamedAddr(UnnamedAddr V) { Ctx.getTracker() .emplaceIfTracking>(this); cast(Val)->setUnnamedAddr(V); } void GlobalValue::setVisibility(VisibilityTypes V) { Ctx.getTracker() .emplaceIfTracking>(this); cast(Val)->setVisibility(V); } NoCFIValue *NoCFIValue::get(GlobalValue *GV) { auto *LLVMC = llvm::NoCFIValue::get(cast(GV->Val)); return cast(GV->getContext().getOrCreateConstant(LLVMC)); } GlobalValue *NoCFIValue::getGlobalValue() const { auto *LLVMC = cast(Val)->getGlobalValue(); return cast(Ctx.getOrCreateConstant(LLVMC)); } PointerType *NoCFIValue::getType() const { return cast(Ctx.getType(cast(Val)->getType())); } ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key, ConstantInt *Disc, Constant *AddrDisc) { auto *LLVMC = llvm::ConstantPtrAuth::get( cast(Ptr->Val), cast(Key->Val), cast(Disc->Val), cast(AddrDisc->Val)); return cast(Ptr->getContext().getOrCreateConstant(LLVMC)); } Constant *ConstantPtrAuth::getPointer() const { return Ctx.getOrCreateConstant( cast(Val)->getPointer()); } ConstantInt *ConstantPtrAuth::getKey() const { return cast( Ctx.getOrCreateConstant(cast(Val)->getKey())); } ConstantInt *ConstantPtrAuth::getDiscriminator() const { return cast(Ctx.getOrCreateConstant( cast(Val)->getDiscriminator())); } Constant *ConstantPtrAuth::getAddrDiscriminator() const { return Ctx.getOrCreateConstant( cast(Val)->getAddrDiscriminator()); } ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const { auto *LLVMC = cast(Val)->getWithSameSchema( cast(Pointer->Val)); return cast(Ctx.getOrCreateConstant(LLVMC)); } BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { auto *LLVMC = llvm::BlockAddress::get(cast(F->Val), cast(BB->Val)); return cast(F->getContext().getOrCreateConstant(LLVMC)); } BlockAddress *BlockAddress::get(BasicBlock *BB) { auto *LLVMC = llvm::BlockAddress::get(cast(BB->Val)); return cast(BB->getContext().getOrCreateConstant(LLVMC)); } BlockAddress *BlockAddress::lookup(const BasicBlock *BB) { auto *LLVMC = llvm::BlockAddress::lookup(cast(BB->Val)); return cast_or_null(BB->getContext().getValue(LLVMC)); } Function *BlockAddress::getFunction() const { return cast( Ctx.getValue(cast(Val)->getFunction())); } BasicBlock *BlockAddress::getBasicBlock() const { return cast( Ctx.getValue(cast(Val)->getBasicBlock())); } DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) { auto *LLVMC = llvm::DSOLocalEquivalent::get(cast(GV->Val)); return cast(GV->getContext().getValue(LLVMC)); } GlobalValue *DSOLocalEquivalent::getGlobalValue() const { return cast( Ctx.getValue(cast(Val)->getGlobalValue())); } } // namespace llvm::sandboxir