1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583 |
- //===-- Constants.cpp - Implement Constant nodes --------------------------===//
- //
- // 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 the Constant* classes.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/IR/Constants.h"
- #include "ConstantFold.h"
- #include "LLVMContextImpl.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringMap.h"
- #include "llvm/IR/BasicBlock.h"
- #include "llvm/IR/DerivedTypes.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/GetElementPtrTypeIterator.h"
- #include "llvm/IR/GlobalAlias.h"
- #include "llvm/IR/GlobalIFunc.h"
- #include "llvm/IR/GlobalValue.h"
- #include "llvm/IR/GlobalVariable.h"
- #include "llvm/IR/Instructions.h"
- #include "llvm/IR/Operator.h"
- #include "llvm/IR/PatternMatch.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/MathExtras.h"
- #include "llvm/Support/raw_ostream.h"
- #include <algorithm>
- using namespace llvm;
- using namespace PatternMatch;
- //===----------------------------------------------------------------------===//
- // Constant Class
- //===----------------------------------------------------------------------===//
- bool Constant::isNegativeZeroValue() const {
- // Floating point values have an explicit -0.0 value.
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return CFP->isZero() && CFP->isNegative();
- // Equivalent for a vector of -0.0's.
- if (getType()->isVectorTy())
- if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue()))
- return SplatCFP->isNegativeZeroValue();
- // We've already handled true FP case; any other FP vectors can't represent -0.0.
- if (getType()->isFPOrFPVectorTy())
- return false;
- // Otherwise, just use +0.0.
- return isNullValue();
- }
- // Return true iff this constant is positive zero (floating point), negative
- // zero (floating point), or a null value.
- bool Constant::isZeroValue() const {
- // Floating point values have an explicit -0.0 value.
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return CFP->isZero();
- // Check for constant splat vectors of 1 values.
- if (getType()->isVectorTy())
- if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue()))
- return SplatCFP->isZero();
- // Otherwise, just use +0.0.
- return isNullValue();
- }
- bool Constant::isNullValue() const {
- // 0 is null.
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
- return CI->isZero();
- // +0.0 is null.
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- // ppc_fp128 determine isZero using high order double only
- // Should check the bitwise value to make sure all bits are zero.
- return CFP->isExactlyValue(+0.0);
- // constant zero is zero for aggregates, cpnull is null for pointers, none for
- // tokens.
- return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this) ||
- isa<ConstantTokenNone>(this);
- }
- bool Constant::isAllOnesValue() const {
- // Check for -1 integers
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
- return CI->isMinusOne();
- // Check for FP which are bitcasted from -1 integers
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().bitcastToAPInt().isAllOnes();
- // Check for constant splat vectors of 1 values.
- if (getType()->isVectorTy())
- if (const auto *SplatVal = getSplatValue())
- return SplatVal->isAllOnesValue();
- return false;
- }
- bool Constant::isOneValue() const {
- // Check for 1 integers
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
- return CI->isOne();
- // Check for FP which are bitcasted from 1 integers
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().bitcastToAPInt().isOne();
- // Check for constant splat vectors of 1 values.
- if (getType()->isVectorTy())
- if (const auto *SplatVal = getSplatValue())
- return SplatVal->isOneValue();
- return false;
- }
- bool Constant::isNotOneValue() const {
- // Check for 1 integers
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
- return !CI->isOneValue();
- // Check for FP which are bitcasted from 1 integers
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return !CFP->getValueAPF().bitcastToAPInt().isOne();
- // Check that vectors don't contain 1
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
- for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
- Constant *Elt = getAggregateElement(I);
- if (!Elt || !Elt->isNotOneValue())
- return false;
- }
- return true;
- }
- // Check for splats that don't contain 1
- if (getType()->isVectorTy())
- if (const auto *SplatVal = getSplatValue())
- return SplatVal->isNotOneValue();
- // It *may* contain 1, we can't tell.
- return false;
- }
- bool Constant::isMinSignedValue() const {
- // Check for INT_MIN integers
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
- return CI->isMinValue(/*isSigned=*/true);
- // Check for FP which are bitcasted from INT_MIN integers
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().bitcastToAPInt().isMinSignedValue();
- // Check for splats of INT_MIN values.
- if (getType()->isVectorTy())
- if (const auto *SplatVal = getSplatValue())
- return SplatVal->isMinSignedValue();
- return false;
- }
- bool Constant::isNotMinSignedValue() const {
- // Check for INT_MIN integers
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
- return !CI->isMinValue(/*isSigned=*/true);
- // Check for FP which are bitcasted from INT_MIN integers
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return !CFP->getValueAPF().bitcastToAPInt().isMinSignedValue();
- // Check that vectors don't contain INT_MIN
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
- for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
- Constant *Elt = getAggregateElement(I);
- if (!Elt || !Elt->isNotMinSignedValue())
- return false;
- }
- return true;
- }
- // Check for splats that aren't INT_MIN
- if (getType()->isVectorTy())
- if (const auto *SplatVal = getSplatValue())
- return SplatVal->isNotMinSignedValue();
- // It *may* contain INT_MIN, we can't tell.
- return false;
- }
- bool Constant::isFiniteNonZeroFP() const {
- if (auto *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().isFiniteNonZero();
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
- for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
- auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I));
- if (!CFP || !CFP->getValueAPF().isFiniteNonZero())
- return false;
- }
- return true;
- }
- if (getType()->isVectorTy())
- if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue()))
- return SplatCFP->isFiniteNonZeroFP();
- // It *may* contain finite non-zero, we can't tell.
- return false;
- }
- bool Constant::isNormalFP() const {
- if (auto *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().isNormal();
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
- for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
- auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I));
- if (!CFP || !CFP->getValueAPF().isNormal())
- return false;
- }
- return true;
- }
- if (getType()->isVectorTy())
- if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue()))
- return SplatCFP->isNormalFP();
- // It *may* contain a normal fp value, we can't tell.
- return false;
- }
- bool Constant::hasExactInverseFP() const {
- if (auto *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().getExactInverse(nullptr);
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
- for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
- auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I));
- if (!CFP || !CFP->getValueAPF().getExactInverse(nullptr))
- return false;
- }
- return true;
- }
- if (getType()->isVectorTy())
- if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue()))
- return SplatCFP->hasExactInverseFP();
- // It *may* have an exact inverse fp value, we can't tell.
- return false;
- }
- bool Constant::isNaN() const {
- if (auto *CFP = dyn_cast<ConstantFP>(this))
- return CFP->isNaN();
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
- for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
- auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I));
- if (!CFP || !CFP->isNaN())
- return false;
- }
- return true;
- }
- if (getType()->isVectorTy())
- if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue()))
- return SplatCFP->isNaN();
- // It *may* be NaN, we can't tell.
- return false;
- }
- bool Constant::isElementWiseEqual(Value *Y) const {
- // Are they fully identical?
- if (this == Y)
- return true;
- // The input value must be a vector constant with the same type.
- auto *VTy = dyn_cast<VectorType>(getType());
- if (!isa<Constant>(Y) || !VTy || VTy != Y->getType())
- return false;
- // TODO: Compare pointer constants?
- if (!(VTy->getElementType()->isIntegerTy() ||
- VTy->getElementType()->isFloatingPointTy()))
- return false;
- // They may still be identical element-wise (if they have `undef`s).
- // Bitcast to integer to allow exact bitwise comparison for all types.
- Type *IntTy = VectorType::getInteger(VTy);
- Constant *C0 = ConstantExpr::getBitCast(const_cast<Constant *>(this), IntTy);
- Constant *C1 = ConstantExpr::getBitCast(cast<Constant>(Y), IntTy);
- Constant *CmpEq = ConstantExpr::getICmp(ICmpInst::ICMP_EQ, C0, C1);
- return isa<UndefValue>(CmpEq) || match(CmpEq, m_One());
- }
- static bool
- containsUndefinedElement(const Constant *C,
- function_ref<bool(const Constant *)> HasFn) {
- if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
- if (HasFn(C))
- return true;
- if (isa<ConstantAggregateZero>(C))
- return false;
- if (isa<ScalableVectorType>(C->getType()))
- return false;
- for (unsigned i = 0, e = cast<FixedVectorType>(VTy)->getNumElements();
- i != e; ++i) {
- if (Constant *Elem = C->getAggregateElement(i))
- if (HasFn(Elem))
- return true;
- }
- }
- return false;
- }
- bool Constant::containsUndefOrPoisonElement() const {
- return containsUndefinedElement(
- this, [&](const auto *C) { return isa<UndefValue>(C); });
- }
- bool Constant::containsPoisonElement() const {
- return containsUndefinedElement(
- this, [&](const auto *C) { return isa<PoisonValue>(C); });
- }
- bool Constant::containsConstantExpression() const {
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
- for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
- if (isa<ConstantExpr>(getAggregateElement(i)))
- return true;
- }
- return false;
- }
- /// Constructor to create a '0' constant of arbitrary type.
- Constant *Constant::getNullValue(Type *Ty) {
- switch (Ty->getTypeID()) {
- case Type::IntegerTyID:
- return ConstantInt::get(Ty, 0);
- case Type::HalfTyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat::getZero(APFloat::IEEEhalf()));
- case Type::BFloatTyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat::getZero(APFloat::BFloat()));
- case Type::FloatTyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat::getZero(APFloat::IEEEsingle()));
- case Type::DoubleTyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat::getZero(APFloat::IEEEdouble()));
- case Type::X86_FP80TyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat::getZero(APFloat::x87DoubleExtended()));
- case Type::FP128TyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat::getZero(APFloat::IEEEquad()));
- case Type::PPC_FP128TyID:
- return ConstantFP::get(Ty->getContext(), APFloat(APFloat::PPCDoubleDouble(),
- APInt::getZero(128)));
- case Type::PointerTyID:
- return ConstantPointerNull::get(cast<PointerType>(Ty));
- case Type::StructTyID:
- case Type::ArrayTyID:
- case Type::FixedVectorTyID:
- case Type::ScalableVectorTyID:
- return ConstantAggregateZero::get(Ty);
- case Type::TokenTyID:
- return ConstantTokenNone::get(Ty->getContext());
- default:
- // Function, Label, or Opaque type?
- llvm_unreachable("Cannot create a null constant of that type!");
- }
- }
- Constant *Constant::getIntegerValue(Type *Ty, const APInt &V) {
- Type *ScalarTy = Ty->getScalarType();
- // Create the base integer constant.
- Constant *C = ConstantInt::get(Ty->getContext(), V);
- // Convert an integer to a pointer, if necessary.
- if (PointerType *PTy = dyn_cast<PointerType>(ScalarTy))
- C = ConstantExpr::getIntToPtr(C, PTy);
- // Broadcast a scalar to a vector, if necessary.
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- C = ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *Constant::getAllOnesValue(Type *Ty) {
- if (IntegerType *ITy = dyn_cast<IntegerType>(Ty))
- return ConstantInt::get(Ty->getContext(),
- APInt::getAllOnes(ITy->getBitWidth()));
- if (Ty->isFloatingPointTy()) {
- APFloat FL = APFloat::getAllOnesValue(Ty->getFltSemantics());
- return ConstantFP::get(Ty->getContext(), FL);
- }
- VectorType *VTy = cast<VectorType>(Ty);
- return ConstantVector::getSplat(VTy->getElementCount(),
- getAllOnesValue(VTy->getElementType()));
- }
- Constant *Constant::getAggregateElement(unsigned Elt) const {
- assert((getType()->isAggregateType() || getType()->isVectorTy()) &&
- "Must be an aggregate/vector constant");
- if (const auto *CC = dyn_cast<ConstantAggregate>(this))
- return Elt < CC->getNumOperands() ? CC->getOperand(Elt) : nullptr;
- if (const auto *CAZ = dyn_cast<ConstantAggregateZero>(this))
- return Elt < CAZ->getElementCount().getKnownMinValue()
- ? CAZ->getElementValue(Elt)
- : nullptr;
- // FIXME: getNumElements() will fail for non-fixed vector types.
- if (isa<ScalableVectorType>(getType()))
- return nullptr;
- if (const auto *PV = dyn_cast<PoisonValue>(this))
- return Elt < PV->getNumElements() ? PV->getElementValue(Elt) : nullptr;
- if (const auto *UV = dyn_cast<UndefValue>(this))
- return Elt < UV->getNumElements() ? UV->getElementValue(Elt) : nullptr;
- if (const auto *CDS = dyn_cast<ConstantDataSequential>(this))
- return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt)
- : nullptr;
- return nullptr;
- }
- Constant *Constant::getAggregateElement(Constant *Elt) const {
- assert(isa<IntegerType>(Elt->getType()) && "Index must be an integer");
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Elt)) {
- // Check if the constant fits into an uint64_t.
- if (CI->getValue().getActiveBits() > 64)
- return nullptr;
- return getAggregateElement(CI->getZExtValue());
- }
- return nullptr;
- }
- void Constant::destroyConstant() {
- /// First call destroyConstantImpl on the subclass. This gives the subclass
- /// a chance to remove the constant from any maps/pools it's contained in.
- switch (getValueID()) {
- default:
- llvm_unreachable("Not a constant!");
- #define HANDLE_CONSTANT(Name) \
- case Value::Name##Val: \
- cast<Name>(this)->destroyConstantImpl(); \
- break;
- #include "llvm/IR/Value.def"
- }
- // When a Constant is destroyed, there may be lingering
- // references to the constant by other constants in the constant pool. These
- // constants are implicitly dependent on the module that is being deleted,
- // but they don't know that. Because we only find out when the CPV is
- // deleted, we must now notify all of our users (that should only be
- // Constants) that they are, in fact, invalid now and should be deleted.
- //
- while (!use_empty()) {
- Value *V = user_back();
- #ifndef NDEBUG // Only in -g mode...
- if (!isa<Constant>(V)) {
- dbgs() << "While deleting: " << *this
- << "\n\nUse still stuck around after Def is destroyed: " << *V
- << "\n\n";
- }
- #endif
- assert(isa<Constant>(V) && "References remain to Constant being destroyed");
- cast<Constant>(V)->destroyConstant();
- // The constant should remove itself from our use list...
- assert((use_empty() || user_back() != V) && "Constant not removed!");
- }
- // Value has no outstanding references it is safe to delete it now...
- deleteConstant(this);
- }
- void llvm::deleteConstant(Constant *C) {
- switch (C->getValueID()) {
- case Constant::ConstantIntVal:
- delete static_cast<ConstantInt *>(C);
- break;
- case Constant::ConstantFPVal:
- delete static_cast<ConstantFP *>(C);
- break;
- case Constant::ConstantAggregateZeroVal:
- delete static_cast<ConstantAggregateZero *>(C);
- break;
- case Constant::ConstantArrayVal:
- delete static_cast<ConstantArray *>(C);
- break;
- case Constant::ConstantStructVal:
- delete static_cast<ConstantStruct *>(C);
- break;
- case Constant::ConstantVectorVal:
- delete static_cast<ConstantVector *>(C);
- break;
- case Constant::ConstantPointerNullVal:
- delete static_cast<ConstantPointerNull *>(C);
- break;
- case Constant::ConstantDataArrayVal:
- delete static_cast<ConstantDataArray *>(C);
- break;
- case Constant::ConstantDataVectorVal:
- delete static_cast<ConstantDataVector *>(C);
- break;
- case Constant::ConstantTokenNoneVal:
- delete static_cast<ConstantTokenNone *>(C);
- break;
- case Constant::BlockAddressVal:
- delete static_cast<BlockAddress *>(C);
- break;
- case Constant::DSOLocalEquivalentVal:
- delete static_cast<DSOLocalEquivalent *>(C);
- break;
- case Constant::NoCFIValueVal:
- delete static_cast<NoCFIValue *>(C);
- break;
- case Constant::UndefValueVal:
- delete static_cast<UndefValue *>(C);
- break;
- case Constant::PoisonValueVal:
- delete static_cast<PoisonValue *>(C);
- break;
- case Constant::ConstantExprVal:
- if (isa<UnaryConstantExpr>(C))
- delete static_cast<UnaryConstantExpr *>(C);
- else if (isa<BinaryConstantExpr>(C))
- delete static_cast<BinaryConstantExpr *>(C);
- else if (isa<SelectConstantExpr>(C))
- delete static_cast<SelectConstantExpr *>(C);
- else if (isa<ExtractElementConstantExpr>(C))
- delete static_cast<ExtractElementConstantExpr *>(C);
- else if (isa<InsertElementConstantExpr>(C))
- delete static_cast<InsertElementConstantExpr *>(C);
- else if (isa<ShuffleVectorConstantExpr>(C))
- delete static_cast<ShuffleVectorConstantExpr *>(C);
- else if (isa<ExtractValueConstantExpr>(C))
- delete static_cast<ExtractValueConstantExpr *>(C);
- else if (isa<InsertValueConstantExpr>(C))
- delete static_cast<InsertValueConstantExpr *>(C);
- else if (isa<GetElementPtrConstantExpr>(C))
- delete static_cast<GetElementPtrConstantExpr *>(C);
- else if (isa<CompareConstantExpr>(C))
- delete static_cast<CompareConstantExpr *>(C);
- else
- llvm_unreachable("Unexpected constant expr");
- break;
- default:
- llvm_unreachable("Unexpected constant");
- }
- }
- static bool canTrapImpl(const Constant *C,
- SmallPtrSetImpl<const ConstantExpr *> &NonTrappingOps) {
- assert(C->getType()->isFirstClassType() && "Cannot evaluate aggregate vals!");
- // The only thing that could possibly trap are constant exprs.
- const ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
- if (!CE)
- return false;
- // ConstantExpr traps if any operands can trap.
- for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
- if (ConstantExpr *Op = dyn_cast<ConstantExpr>(CE->getOperand(i))) {
- if (NonTrappingOps.insert(Op).second && canTrapImpl(Op, NonTrappingOps))
- return true;
- }
- }
- // Otherwise, only specific operations can trap.
- switch (CE->getOpcode()) {
- default:
- return false;
- case Instruction::UDiv:
- case Instruction::SDiv:
- case Instruction::URem:
- case Instruction::SRem:
- // Div and rem can trap if the RHS is not known to be non-zero.
- if (!isa<ConstantInt>(CE->getOperand(1)) ||CE->getOperand(1)->isNullValue())
- return true;
- return false;
- }
- }
- bool Constant::canTrap() const {
- SmallPtrSet<const ConstantExpr *, 4> NonTrappingOps;
- return canTrapImpl(this, NonTrappingOps);
- }
- /// Check if C contains a GlobalValue for which Predicate is true.
- static bool
- ConstHasGlobalValuePredicate(const Constant *C,
- bool (*Predicate)(const GlobalValue *)) {
- SmallPtrSet<const Constant *, 8> Visited;
- SmallVector<const Constant *, 8> WorkList;
- WorkList.push_back(C);
- Visited.insert(C);
- while (!WorkList.empty()) {
- const Constant *WorkItem = WorkList.pop_back_val();
- if (const auto *GV = dyn_cast<GlobalValue>(WorkItem))
- if (Predicate(GV))
- return true;
- for (const Value *Op : WorkItem->operands()) {
- const Constant *ConstOp = dyn_cast<Constant>(Op);
- if (!ConstOp)
- continue;
- if (Visited.insert(ConstOp).second)
- WorkList.push_back(ConstOp);
- }
- }
- return false;
- }
- bool Constant::isThreadDependent() const {
- auto DLLImportPredicate = [](const GlobalValue *GV) {
- return GV->isThreadLocal();
- };
- return ConstHasGlobalValuePredicate(this, DLLImportPredicate);
- }
- bool Constant::isDLLImportDependent() const {
- auto DLLImportPredicate = [](const GlobalValue *GV) {
- return GV->hasDLLImportStorageClass();
- };
- return ConstHasGlobalValuePredicate(this, DLLImportPredicate);
- }
- bool Constant::isConstantUsed() const {
- for (const User *U : users()) {
- const Constant *UC = dyn_cast<Constant>(U);
- if (!UC || isa<GlobalValue>(UC))
- return true;
- if (UC->isConstantUsed())
- return true;
- }
- return false;
- }
- bool Constant::needsDynamicRelocation() const {
- return getRelocationInfo() == GlobalRelocation;
- }
- bool Constant::needsRelocation() const {
- return getRelocationInfo() != NoRelocation;
- }
- Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
- if (isa<GlobalValue>(this))
- return GlobalRelocation; // Global reference.
- if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
- return BA->getFunction()->getRelocationInfo();
- if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
- if (CE->getOpcode() == Instruction::Sub) {
- ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
- ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
- if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
- RHS->getOpcode() == Instruction::PtrToInt) {
- Constant *LHSOp0 = LHS->getOperand(0);
- Constant *RHSOp0 = RHS->getOperand(0);
- // While raw uses of blockaddress need to be relocated, differences
- // between two of them don't when they are for labels in the same
- // function. This is a common idiom when creating a table for the
- // indirect goto extension, so we handle it efficiently here.
- if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(RHSOp0) &&
- cast<BlockAddress>(LHSOp0)->getFunction() ==
- cast<BlockAddress>(RHSOp0)->getFunction())
- return NoRelocation;
- // Relative pointers do not need to be dynamically relocated.
- if (auto *RHSGV =
- dyn_cast<GlobalValue>(RHSOp0->stripInBoundsConstantOffsets())) {
- auto *LHS = LHSOp0->stripInBoundsConstantOffsets();
- if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) {
- if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
- return LocalRelocation;
- } else if (isa<DSOLocalEquivalent>(LHS)) {
- if (RHSGV->isDSOLocal())
- return LocalRelocation;
- }
- }
- }
- }
- }
- PossibleRelocationsTy Result = NoRelocation;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- Result =
- std::max(cast<Constant>(getOperand(i))->getRelocationInfo(), Result);
- return Result;
- }
- /// Return true if the specified constantexpr is dead. This involves
- /// recursively traversing users of the constantexpr.
- /// If RemoveDeadUsers is true, also remove dead users at the same time.
- static bool constantIsDead(const Constant *C, bool RemoveDeadUsers) {
- if (isa<GlobalValue>(C)) return false; // Cannot remove this
- Value::const_user_iterator I = C->user_begin(), E = C->user_end();
- while (I != E) {
- const Constant *User = dyn_cast<Constant>(*I);
- if (!User) return false; // Non-constant usage;
- if (!constantIsDead(User, RemoveDeadUsers))
- return false; // Constant wasn't dead
- // Just removed User, so the iterator was invalidated.
- // Since we return immediately upon finding a live user, we can always
- // restart from user_begin().
- if (RemoveDeadUsers)
- I = C->user_begin();
- else
- ++I;
- }
- if (RemoveDeadUsers)
- const_cast<Constant *>(C)->destroyConstant();
- return true;
- }
- void Constant::removeDeadConstantUsers() const {
- Value::const_user_iterator I = user_begin(), E = user_end();
- Value::const_user_iterator LastNonDeadUser = E;
- while (I != E) {
- const Constant *User = dyn_cast<Constant>(*I);
- if (!User) {
- LastNonDeadUser = I;
- ++I;
- continue;
- }
- if (!constantIsDead(User, /* RemoveDeadUsers= */ true)) {
- // If the constant wasn't dead, remember that this was the last live use
- // and move on to the next constant.
- LastNonDeadUser = I;
- ++I;
- continue;
- }
- // If the constant was dead, then the iterator is invalidated.
- if (LastNonDeadUser == E)
- I = user_begin();
- else
- I = std::next(LastNonDeadUser);
- }
- }
- bool Constant::hasOneLiveUse() const { return hasNLiveUses(1); }
- bool Constant::hasZeroLiveUses() const { return hasNLiveUses(0); }
- bool Constant::hasNLiveUses(unsigned N) const {
- unsigned NumUses = 0;
- for (const Use &U : uses()) {
- const Constant *User = dyn_cast<Constant>(U.getUser());
- if (!User || !constantIsDead(User, /* RemoveDeadUsers= */ false)) {
- ++NumUses;
- if (NumUses > N)
- return false;
- }
- }
- return NumUses == N;
- }
- Constant *Constant::replaceUndefsWith(Constant *C, Constant *Replacement) {
- assert(C && Replacement && "Expected non-nullptr constant arguments");
- Type *Ty = C->getType();
- if (match(C, m_Undef())) {
- assert(Ty == Replacement->getType() && "Expected matching types");
- return Replacement;
- }
- // Don't know how to deal with this constant.
- auto *VTy = dyn_cast<FixedVectorType>(Ty);
- if (!VTy)
- return C;
- unsigned NumElts = VTy->getNumElements();
- SmallVector<Constant *, 32> NewC(NumElts);
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *EltC = C->getAggregateElement(i);
- assert((!EltC || EltC->getType() == Replacement->getType()) &&
- "Expected matching types");
- NewC[i] = EltC && match(EltC, m_Undef()) ? Replacement : EltC;
- }
- return ConstantVector::get(NewC);
- }
- Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {
- assert(C && Other && "Expected non-nullptr constant arguments");
- if (match(C, m_Undef()))
- return C;
- Type *Ty = C->getType();
- if (match(Other, m_Undef()))
- return UndefValue::get(Ty);
- auto *VTy = dyn_cast<FixedVectorType>(Ty);
- if (!VTy)
- return C;
- Type *EltTy = VTy->getElementType();
- unsigned NumElts = VTy->getNumElements();
- assert(isa<FixedVectorType>(Other->getType()) &&
- cast<FixedVectorType>(Other->getType())->getNumElements() == NumElts &&
- "Type mismatch");
- bool FoundExtraUndef = false;
- SmallVector<Constant *, 32> NewC(NumElts);
- for (unsigned I = 0; I != NumElts; ++I) {
- NewC[I] = C->getAggregateElement(I);
- Constant *OtherEltC = Other->getAggregateElement(I);
- assert(NewC[I] && OtherEltC && "Unknown vector element");
- if (!match(NewC[I], m_Undef()) && match(OtherEltC, m_Undef())) {
- NewC[I] = UndefValue::get(EltTy);
- FoundExtraUndef = true;
- }
- }
- if (FoundExtraUndef)
- return ConstantVector::get(NewC);
- return C;
- }
- bool Constant::isManifestConstant() const {
- if (isa<ConstantData>(this))
- return true;
- if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) {
- for (const Value *Op : operand_values())
- if (!cast<Constant>(Op)->isManifestConstant())
- return false;
- return true;
- }
- return false;
- }
- //===----------------------------------------------------------------------===//
- // ConstantInt
- //===----------------------------------------------------------------------===//
- ConstantInt::ConstantInt(IntegerType *Ty, const APInt &V)
- : ConstantData(Ty, ConstantIntVal), Val(V) {
- assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
- }
- ConstantInt *ConstantInt::getTrue(LLVMContext &Context) {
- LLVMContextImpl *pImpl = Context.pImpl;
- if (!pImpl->TheTrueVal)
- pImpl->TheTrueVal = ConstantInt::get(Type::getInt1Ty(Context), 1);
- return pImpl->TheTrueVal;
- }
- ConstantInt *ConstantInt::getFalse(LLVMContext &Context) {
- LLVMContextImpl *pImpl = Context.pImpl;
- if (!pImpl->TheFalseVal)
- pImpl->TheFalseVal = ConstantInt::get(Type::getInt1Ty(Context), 0);
- return pImpl->TheFalseVal;
- }
- ConstantInt *ConstantInt::getBool(LLVMContext &Context, bool V) {
- return V ? getTrue(Context) : getFalse(Context);
- }
- Constant *ConstantInt::getTrue(Type *Ty) {
- assert(Ty->isIntOrIntVectorTy(1) && "Type not i1 or vector of i1.");
- ConstantInt *TrueC = ConstantInt::getTrue(Ty->getContext());
- if (auto *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), TrueC);
- return TrueC;
- }
- Constant *ConstantInt::getFalse(Type *Ty) {
- assert(Ty->isIntOrIntVectorTy(1) && "Type not i1 or vector of i1.");
- ConstantInt *FalseC = ConstantInt::getFalse(Ty->getContext());
- if (auto *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), FalseC);
- return FalseC;
- }
- Constant *ConstantInt::getBool(Type *Ty, bool V) {
- return V ? getTrue(Ty) : getFalse(Ty);
- }
- // Get a ConstantInt from an APInt.
- ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) {
- // get an existing value or the insertion position
- LLVMContextImpl *pImpl = Context.pImpl;
- std::unique_ptr<ConstantInt> &Slot = pImpl->IntConstants[V];
- if (!Slot) {
- // Get the corresponding integer type for the bit width of the value.
- IntegerType *ITy = IntegerType::get(Context, V.getBitWidth());
- Slot.reset(new ConstantInt(ITy, V));
- }
- assert(Slot->getType() == IntegerType::get(Context, V.getBitWidth()));
- return Slot.get();
- }
- Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {
- Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned);
- // For vectors, broadcast the value.
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool isSigned) {
- return get(Ty->getContext(), APInt(Ty->getBitWidth(), V, isSigned));
- }
- ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
- return get(Ty, V, true);
- }
- Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
- return get(Ty, V, true);
- }
- Constant *ConstantInt::get(Type *Ty, const APInt& V) {
- ConstantInt *C = get(Ty->getContext(), V);
- assert(C->getType() == Ty->getScalarType() &&
- "ConstantInt type doesn't match the type implied by its value!");
- // For vectors, broadcast the value.
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str, uint8_t radix) {
- return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix));
- }
- /// Remove the constant from the constant table.
- void ConstantInt::destroyConstantImpl() {
- llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!");
- }
- //===----------------------------------------------------------------------===//
- // ConstantFP
- //===----------------------------------------------------------------------===//
- Constant *ConstantFP::get(Type *Ty, double V) {
- LLVMContext &Context = Ty->getContext();
- APFloat FV(V);
- bool ignored;
- FV.convert(Ty->getScalarType()->getFltSemantics(),
- APFloat::rmNearestTiesToEven, &ignored);
- Constant *C = get(Context, FV);
- // For vectors, broadcast the value.
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *ConstantFP::get(Type *Ty, const APFloat &V) {
- ConstantFP *C = get(Ty->getContext(), V);
- assert(C->getType() == Ty->getScalarType() &&
- "ConstantFP type doesn't match the type implied by its value!");
- // For vectors, broadcast the value.
- if (auto *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *ConstantFP::get(Type *Ty, StringRef Str) {
- LLVMContext &Context = Ty->getContext();
- APFloat FV(Ty->getScalarType()->getFltSemantics(), Str);
- Constant *C = get(Context, FV);
- // For vectors, broadcast the value.
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
- APFloat NaN = APFloat::getNaN(Semantics, Negative, Payload);
- Constant *C = get(Ty->getContext(), NaN);
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
- APFloat NaN = APFloat::getQNaN(Semantics, Negative, Payload);
- Constant *C = get(Ty->getContext(), NaN);
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
- APFloat NaN = APFloat::getSNaN(Semantics, Negative, Payload);
- Constant *C = get(Ty->getContext(), NaN);
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *ConstantFP::getNegativeZero(Type *Ty) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
- APFloat NegZero = APFloat::getZero(Semantics, /*Negative=*/true);
- Constant *C = get(Ty->getContext(), NegZero);
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- Constant *ConstantFP::getZeroValueForNegation(Type *Ty) {
- if (Ty->isFPOrFPVectorTy())
- return getNegativeZero(Ty);
- return Constant::getNullValue(Ty);
- }
- // ConstantFP accessors.
- ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {
- LLVMContextImpl* pImpl = Context.pImpl;
- std::unique_ptr<ConstantFP> &Slot = pImpl->FPConstants[V];
- if (!Slot) {
- Type *Ty = Type::getFloatingPointTy(Context, V.getSemantics());
- Slot.reset(new ConstantFP(Ty, V));
- }
- return Slot.get();
- }
- Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
- Constant *C = get(Ty->getContext(), APFloat::getInf(Semantics, Negative));
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getElementCount(), C);
- return C;
- }
- ConstantFP::ConstantFP(Type *Ty, const APFloat &V)
- : ConstantData(Ty, ConstantFPVal), Val(V) {
- assert(&V.getSemantics() == &Ty->getFltSemantics() &&
- "FP type Mismatch");
- }
- bool ConstantFP::isExactlyValue(const APFloat &V) const {
- return Val.bitwiseIsEqual(V);
- }
- /// Remove the constant from the constant table.
- void ConstantFP::destroyConstantImpl() {
- llvm_unreachable("You can't ConstantFP->destroyConstantImpl()!");
- }
- //===----------------------------------------------------------------------===//
- // ConstantAggregateZero Implementation
- //===----------------------------------------------------------------------===//
- Constant *ConstantAggregateZero::getSequentialElement() const {
- if (auto *AT = dyn_cast<ArrayType>(getType()))
- return Constant::getNullValue(AT->getElementType());
- return Constant::getNullValue(cast<VectorType>(getType())->getElementType());
- }
- Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {
- return Constant::getNullValue(getType()->getStructElementType(Elt));
- }
- Constant *ConstantAggregateZero::getElementValue(Constant *C) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(cast<ConstantInt>(C)->getZExtValue());
- }
- Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(Idx);
- }
- ElementCount ConstantAggregateZero::getElementCount() const {
- Type *Ty = getType();
- if (auto *AT = dyn_cast<ArrayType>(Ty))
- return ElementCount::getFixed(AT->getNumElements());
- if (auto *VT = dyn_cast<VectorType>(Ty))
- return VT->getElementCount();
- return ElementCount::getFixed(Ty->getStructNumElements());
- }
- //===----------------------------------------------------------------------===//
- // UndefValue Implementation
- //===----------------------------------------------------------------------===//
- UndefValue *UndefValue::getSequentialElement() const {
- if (ArrayType *ATy = dyn_cast<ArrayType>(getType()))
- return UndefValue::get(ATy->getElementType());
- return UndefValue::get(cast<VectorType>(getType())->getElementType());
- }
- UndefValue *UndefValue::getStructElement(unsigned Elt) const {
- return UndefValue::get(getType()->getStructElementType(Elt));
- }
- UndefValue *UndefValue::getElementValue(Constant *C) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(cast<ConstantInt>(C)->getZExtValue());
- }
- UndefValue *UndefValue::getElementValue(unsigned Idx) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(Idx);
- }
- unsigned UndefValue::getNumElements() const {
- Type *Ty = getType();
- if (auto *AT = dyn_cast<ArrayType>(Ty))
- return AT->getNumElements();
- if (auto *VT = dyn_cast<VectorType>(Ty))
- return cast<FixedVectorType>(VT)->getNumElements();
- return Ty->getStructNumElements();
- }
- //===----------------------------------------------------------------------===//
- // PoisonValue Implementation
- //===----------------------------------------------------------------------===//
- PoisonValue *PoisonValue::getSequentialElement() const {
- if (ArrayType *ATy = dyn_cast<ArrayType>(getType()))
- return PoisonValue::get(ATy->getElementType());
- return PoisonValue::get(cast<VectorType>(getType())->getElementType());
- }
- PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {
- return PoisonValue::get(getType()->getStructElementType(Elt));
- }
- PoisonValue *PoisonValue::getElementValue(Constant *C) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(cast<ConstantInt>(C)->getZExtValue());
- }
- PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(Idx);
- }
- //===----------------------------------------------------------------------===//
- // ConstantXXX Classes
- //===----------------------------------------------------------------------===//
- template <typename ItTy, typename EltTy>
- static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) {
- for (; Start != End; ++Start)
- if (*Start != Elt)
- return false;
- return true;
- }
- template <typename SequentialTy, typename ElementTy>
- static Constant *getIntSequenceIfElementsMatch(ArrayRef<Constant *> V) {
- assert(!V.empty() && "Cannot get empty int sequence.");
- SmallVector<ElementTy, 16> Elts;
- for (Constant *C : V)
- if (auto *CI = dyn_cast<ConstantInt>(C))
- Elts.push_back(CI->getZExtValue());
- else
- return nullptr;
- return SequentialTy::get(V[0]->getContext(), Elts);
- }
- template <typename SequentialTy, typename ElementTy>
- static Constant *getFPSequenceIfElementsMatch(ArrayRef<Constant *> V) {
- assert(!V.empty() && "Cannot get empty FP sequence.");
- SmallVector<ElementTy, 16> Elts;
- for (Constant *C : V)
- if (auto *CFP = dyn_cast<ConstantFP>(C))
- Elts.push_back(CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- else
- return nullptr;
- return SequentialTy::getFP(V[0]->getType(), Elts);
- }
- template <typename SequenceTy>
- static Constant *getSequenceIfElementsMatch(Constant *C,
- ArrayRef<Constant *> V) {
- // We speculatively build the elements here even if it turns out that there is
- // a constantexpr or something else weird, since it is so uncommon for that to
- // happen.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) {
- if (CI->getType()->isIntegerTy(8))
- return getIntSequenceIfElementsMatch<SequenceTy, uint8_t>(V);
- else if (CI->getType()->isIntegerTy(16))
- return getIntSequenceIfElementsMatch<SequenceTy, uint16_t>(V);
- else if (CI->getType()->isIntegerTy(32))
- return getIntSequenceIfElementsMatch<SequenceTy, uint32_t>(V);
- else if (CI->getType()->isIntegerTy(64))
- return getIntSequenceIfElementsMatch<SequenceTy, uint64_t>(V);
- } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
- if (CFP->getType()->isHalfTy() || CFP->getType()->isBFloatTy())
- return getFPSequenceIfElementsMatch<SequenceTy, uint16_t>(V);
- else if (CFP->getType()->isFloatTy())
- return getFPSequenceIfElementsMatch<SequenceTy, uint32_t>(V);
- else if (CFP->getType()->isDoubleTy())
- return getFPSequenceIfElementsMatch<SequenceTy, uint64_t>(V);
- }
- return nullptr;
- }
- ConstantAggregate::ConstantAggregate(Type *T, ValueTy VT,
- ArrayRef<Constant *> V)
- : Constant(T, VT, OperandTraits<ConstantAggregate>::op_end(this) - V.size(),
- V.size()) {
- llvm::copy(V, op_begin());
- // Check that types match, unless this is an opaque struct.
- if (auto *ST = dyn_cast<StructType>(T)) {
- if (ST->isOpaque())
- return;
- for (unsigned I = 0, E = V.size(); I != E; ++I)
- assert(V[I]->getType() == ST->getTypeAtIndex(I) &&
- "Initializer for struct element doesn't match!");
- }
- }
- ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
- : ConstantAggregate(T, ConstantArrayVal, V) {
- assert(V.size() == T->getNumElements() &&
- "Invalid initializer for constant array");
- }
- Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
- if (Constant *C = getImpl(Ty, V))
- return C;
- return Ty->getContext().pImpl->ArrayConstants.getOrCreate(Ty, V);
- }
- Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
- // Empty arrays are canonicalized to ConstantAggregateZero.
- if (V.empty())
- return ConstantAggregateZero::get(Ty);
- for (Constant *C : V) {
- assert(C->getType() == Ty->getElementType() &&
- "Wrong type in array element initializer");
- (void)C;
- }
- // If this is an all-zero array, return a ConstantAggregateZero object. If
- // all undef, return an UndefValue, if "all simple", then return a
- // ConstantDataArray.
- Constant *C = V[0];
- if (isa<PoisonValue>(C) && rangeOnlyContains(V.begin(), V.end(), C))
- return PoisonValue::get(Ty);
- if (isa<UndefValue>(C) && rangeOnlyContains(V.begin(), V.end(), C))
- return UndefValue::get(Ty);
- if (C->isNullValue() && rangeOnlyContains(V.begin(), V.end(), C))
- return ConstantAggregateZero::get(Ty);
- // Check to see if all of the elements are ConstantFP or ConstantInt and if
- // the element type is compatible with ConstantDataVector. If so, use it.
- if (ConstantDataSequential::isElementTypeCompatible(C->getType()))
- return getSequenceIfElementsMatch<ConstantDataArray>(C, V);
- // Otherwise, we really do want to create a ConstantArray.
- return nullptr;
- }
- StructType *ConstantStruct::getTypeForElements(LLVMContext &Context,
- ArrayRef<Constant*> V,
- bool Packed) {
- unsigned VecSize = V.size();
- SmallVector<Type*, 16> EltTypes(VecSize);
- for (unsigned i = 0; i != VecSize; ++i)
- EltTypes[i] = V[i]->getType();
- return StructType::get(Context, EltTypes, Packed);
- }
- StructType *ConstantStruct::getTypeForElements(ArrayRef<Constant*> V,
- bool Packed) {
- assert(!V.empty() &&
- "ConstantStruct::getTypeForElements cannot be called on empty list");
- return getTypeForElements(V[0]->getContext(), V, Packed);
- }
- ConstantStruct::ConstantStruct(StructType *T, ArrayRef<Constant *> V)
- : ConstantAggregate(T, ConstantStructVal, V) {
- assert((T->isOpaque() || V.size() == T->getNumElements()) &&
- "Invalid initializer for constant struct");
- }
- // ConstantStruct accessors.
- Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) {
- assert((ST->isOpaque() || ST->getNumElements() == V.size()) &&
- "Incorrect # elements specified to ConstantStruct::get");
- // Create a ConstantAggregateZero value if all elements are zeros.
- bool isZero = true;
- bool isUndef = false;
- bool isPoison = false;
- if (!V.empty()) {
- isUndef = isa<UndefValue>(V[0]);
- isPoison = isa<PoisonValue>(V[0]);
- isZero = V[0]->isNullValue();
- // PoisonValue inherits UndefValue, so its check is not necessary.
- if (isUndef || isZero) {
- for (Constant *C : V) {
- if (!C->isNullValue())
- isZero = false;
- if (!isa<PoisonValue>(C))
- isPoison = false;
- if (isa<PoisonValue>(C) || !isa<UndefValue>(C))
- isUndef = false;
- }
- }
- }
- if (isZero)
- return ConstantAggregateZero::get(ST);
- if (isPoison)
- return PoisonValue::get(ST);
- if (isUndef)
- return UndefValue::get(ST);
- return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V);
- }
- ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V)
- : ConstantAggregate(T, ConstantVectorVal, V) {
- assert(V.size() == cast<FixedVectorType>(T)->getNumElements() &&
- "Invalid initializer for constant vector");
- }
- // ConstantVector accessors.
- Constant *ConstantVector::get(ArrayRef<Constant*> V) {
- if (Constant *C = getImpl(V))
- return C;
- auto *Ty = FixedVectorType::get(V.front()->getType(), V.size());
- return Ty->getContext().pImpl->VectorConstants.getOrCreate(Ty, V);
- }
- Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
- assert(!V.empty() && "Vectors can't be empty");
- auto *T = FixedVectorType::get(V.front()->getType(), V.size());
- // If this is an all-undef or all-zero vector, return a
- // ConstantAggregateZero or UndefValue.
- Constant *C = V[0];
- bool isZero = C->isNullValue();
- bool isUndef = isa<UndefValue>(C);
- bool isPoison = isa<PoisonValue>(C);
- if (isZero || isUndef) {
- for (unsigned i = 1, e = V.size(); i != e; ++i)
- if (V[i] != C) {
- isZero = isUndef = isPoison = false;
- break;
- }
- }
- if (isZero)
- return ConstantAggregateZero::get(T);
- if (isPoison)
- return PoisonValue::get(T);
- if (isUndef)
- return UndefValue::get(T);
- // Check to see if all of the elements are ConstantFP or ConstantInt and if
- // the element type is compatible with ConstantDataVector. If so, use it.
- if (ConstantDataSequential::isElementTypeCompatible(C->getType()))
- return getSequenceIfElementsMatch<ConstantDataVector>(C, V);
- // Otherwise, the element type isn't compatible with ConstantDataVector, or
- // the operand list contains a ConstantExpr or something else strange.
- return nullptr;
- }
- Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
- if (!EC.isScalable()) {
- // If this splat is compatible with ConstantDataVector, use it instead of
- // ConstantVector.
- if ((isa<ConstantFP>(V) || isa<ConstantInt>(V)) &&
- ConstantDataSequential::isElementTypeCompatible(V->getType()))
- return ConstantDataVector::getSplat(EC.getKnownMinValue(), V);
- SmallVector<Constant *, 32> Elts(EC.getKnownMinValue(), V);
- return get(Elts);
- }
- Type *VTy = VectorType::get(V->getType(), EC);
- if (V->isNullValue())
- return ConstantAggregateZero::get(VTy);
- else if (isa<UndefValue>(V))
- return UndefValue::get(VTy);
- Type *I32Ty = Type::getInt32Ty(VTy->getContext());
- // Move scalar into vector.
- Constant *PoisonV = PoisonValue::get(VTy);
- V = ConstantExpr::getInsertElement(PoisonV, V, ConstantInt::get(I32Ty, 0));
- // Build shuffle mask to perform the splat.
- SmallVector<int, 8> Zeros(EC.getKnownMinValue(), 0);
- // Splat.
- return ConstantExpr::getShuffleVector(V, PoisonV, Zeros);
- }
- ConstantTokenNone *ConstantTokenNone::get(LLVMContext &Context) {
- LLVMContextImpl *pImpl = Context.pImpl;
- if (!pImpl->TheNoneToken)
- pImpl->TheNoneToken.reset(new ConstantTokenNone(Context));
- return pImpl->TheNoneToken.get();
- }
- /// Remove the constant from the constant table.
- void ConstantTokenNone::destroyConstantImpl() {
- llvm_unreachable("You can't ConstantTokenNone->destroyConstantImpl()!");
- }
- // Utility function for determining if a ConstantExpr is a CastOp or not. This
- // can't be inline because we don't want to #include Instruction.h into
- // Constant.h
- bool ConstantExpr::isCast() const {
- return Instruction::isCast(getOpcode());
- }
- bool ConstantExpr::isCompare() const {
- return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
- }
- bool ConstantExpr::hasIndices() const {
- return getOpcode() == Instruction::ExtractValue ||
- getOpcode() == Instruction::InsertValue;
- }
- ArrayRef<unsigned> ConstantExpr::getIndices() const {
- if (const ExtractValueConstantExpr *EVCE =
- dyn_cast<ExtractValueConstantExpr>(this))
- return EVCE->Indices;
- return cast<InsertValueConstantExpr>(this)->Indices;
- }
- unsigned ConstantExpr::getPredicate() const {
- return cast<CompareConstantExpr>(this)->predicate;
- }
- ArrayRef<int> ConstantExpr::getShuffleMask() const {
- return cast<ShuffleVectorConstantExpr>(this)->ShuffleMask;
- }
- Constant *ConstantExpr::getShuffleMaskForBitcode() const {
- return cast<ShuffleVectorConstantExpr>(this)->ShuffleMaskForBitcode;
- }
- Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
- bool OnlyIfReduced, Type *SrcTy) const {
- assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
- // If no operands changed return self.
- if (Ty == getType() && std::equal(Ops.begin(), Ops.end(), op_begin()))
- return const_cast<ConstantExpr*>(this);
- Type *OnlyIfReducedTy = OnlyIfReduced ? Ty : nullptr;
- switch (getOpcode()) {
- case Instruction::Trunc:
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- case Instruction::PtrToInt:
- case Instruction::IntToPtr:
- case Instruction::BitCast:
- case Instruction::AddrSpaceCast:
- return ConstantExpr::getCast(getOpcode(), Ops[0], Ty, OnlyIfReduced);
- case Instruction::Select:
- return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2], OnlyIfReducedTy);
- case Instruction::InsertElement:
- return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2],
- OnlyIfReducedTy);
- case Instruction::ExtractElement:
- return ConstantExpr::getExtractElement(Ops[0], Ops[1], OnlyIfReducedTy);
- case Instruction::InsertValue:
- return ConstantExpr::getInsertValue(Ops[0], Ops[1], getIndices(),
- OnlyIfReducedTy);
- case Instruction::ExtractValue:
- return ConstantExpr::getExtractValue(Ops[0], getIndices(), OnlyIfReducedTy);
- case Instruction::FNeg:
- return ConstantExpr::getFNeg(Ops[0]);
- case Instruction::ShuffleVector:
- return ConstantExpr::getShuffleVector(Ops[0], Ops[1], getShuffleMask(),
- OnlyIfReducedTy);
- case Instruction::GetElementPtr: {
- auto *GEPO = cast<GEPOperator>(this);
- assert(SrcTy || (Ops[0]->getType() == getOperand(0)->getType()));
- return ConstantExpr::getGetElementPtr(
- SrcTy ? SrcTy : GEPO->getSourceElementType(), Ops[0], Ops.slice(1),
- GEPO->isInBounds(), GEPO->getInRangeIndex(), OnlyIfReducedTy);
- }
- case Instruction::ICmp:
- case Instruction::FCmp:
- return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1],
- OnlyIfReducedTy);
- default:
- assert(getNumOperands() == 2 && "Must be binary operator?");
- return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassOptionalData,
- OnlyIfReducedTy);
- }
- }
- //===----------------------------------------------------------------------===//
- // isValueValidForType implementations
- bool ConstantInt::isValueValidForType(Type *Ty, uint64_t Val) {
- unsigned NumBits = Ty->getIntegerBitWidth(); // assert okay
- if (Ty->isIntegerTy(1))
- return Val == 0 || Val == 1;
- return isUIntN(NumBits, Val);
- }
- bool ConstantInt::isValueValidForType(Type *Ty, int64_t Val) {
- unsigned NumBits = Ty->getIntegerBitWidth();
- if (Ty->isIntegerTy(1))
- return Val == 0 || Val == 1 || Val == -1;
- return isIntN(NumBits, Val);
- }
- bool ConstantFP::isValueValidForType(Type *Ty, const APFloat& Val) {
- // convert modifies in place, so make a copy.
- APFloat Val2 = APFloat(Val);
- bool losesInfo;
- switch (Ty->getTypeID()) {
- default:
- return false; // These can't be represented as floating point!
- // FIXME rounding mode needs to be more flexible
- case Type::HalfTyID: {
- if (&Val2.getSemantics() == &APFloat::IEEEhalf())
- return true;
- Val2.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &losesInfo);
- return !losesInfo;
- }
- case Type::BFloatTyID: {
- if (&Val2.getSemantics() == &APFloat::BFloat())
- return true;
- Val2.convert(APFloat::BFloat(), APFloat::rmNearestTiesToEven, &losesInfo);
- return !losesInfo;
- }
- case Type::FloatTyID: {
- if (&Val2.getSemantics() == &APFloat::IEEEsingle())
- return true;
- Val2.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);
- return !losesInfo;
- }
- case Type::DoubleTyID: {
- if (&Val2.getSemantics() == &APFloat::IEEEhalf() ||
- &Val2.getSemantics() == &APFloat::BFloat() ||
- &Val2.getSemantics() == &APFloat::IEEEsingle() ||
- &Val2.getSemantics() == &APFloat::IEEEdouble())
- return true;
- Val2.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
- return !losesInfo;
- }
- case Type::X86_FP80TyID:
- return &Val2.getSemantics() == &APFloat::IEEEhalf() ||
- &Val2.getSemantics() == &APFloat::BFloat() ||
- &Val2.getSemantics() == &APFloat::IEEEsingle() ||
- &Val2.getSemantics() == &APFloat::IEEEdouble() ||
- &Val2.getSemantics() == &APFloat::x87DoubleExtended();
- case Type::FP128TyID:
- return &Val2.getSemantics() == &APFloat::IEEEhalf() ||
- &Val2.getSemantics() == &APFloat::BFloat() ||
- &Val2.getSemantics() == &APFloat::IEEEsingle() ||
- &Val2.getSemantics() == &APFloat::IEEEdouble() ||
- &Val2.getSemantics() == &APFloat::IEEEquad();
- case Type::PPC_FP128TyID:
- return &Val2.getSemantics() == &APFloat::IEEEhalf() ||
- &Val2.getSemantics() == &APFloat::BFloat() ||
- &Val2.getSemantics() == &APFloat::IEEEsingle() ||
- &Val2.getSemantics() == &APFloat::IEEEdouble() ||
- &Val2.getSemantics() == &APFloat::PPCDoubleDouble();
- }
- }
- //===----------------------------------------------------------------------===//
- // Factory Function Implementation
- ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {
- assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) &&
- "Cannot create an aggregate zero of non-aggregate type!");
- std::unique_ptr<ConstantAggregateZero> &Entry =
- Ty->getContext().pImpl->CAZConstants[Ty];
- if (!Entry)
- Entry.reset(new ConstantAggregateZero(Ty));
- return Entry.get();
- }
- /// Remove the constant from the constant table.
- void ConstantAggregateZero::destroyConstantImpl() {
- getContext().pImpl->CAZConstants.erase(getType());
- }
- /// Remove the constant from the constant table.
- void ConstantArray::destroyConstantImpl() {
- getType()->getContext().pImpl->ArrayConstants.remove(this);
- }
- //---- ConstantStruct::get() implementation...
- //
- /// Remove the constant from the constant table.
- void ConstantStruct::destroyConstantImpl() {
- getType()->getContext().pImpl->StructConstants.remove(this);
- }
- /// Remove the constant from the constant table.
- void ConstantVector::destroyConstantImpl() {
- getType()->getContext().pImpl->VectorConstants.remove(this);
- }
- Constant *Constant::getSplatValue(bool AllowUndefs) const {
- assert(this->getType()->isVectorTy() && "Only valid for vectors!");
- if (isa<ConstantAggregateZero>(this))
- return getNullValue(cast<VectorType>(getType())->getElementType());
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
- return CV->getSplatValue();
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
- return CV->getSplatValue(AllowUndefs);
- // Check if this is a constant expression splat of the form returned by
- // ConstantVector::getSplat()
- const auto *Shuf = dyn_cast<ConstantExpr>(this);
- if (Shuf && Shuf->getOpcode() == Instruction::ShuffleVector &&
- isa<UndefValue>(Shuf->getOperand(1))) {
- const auto *IElt = dyn_cast<ConstantExpr>(Shuf->getOperand(0));
- if (IElt && IElt->getOpcode() == Instruction::InsertElement &&
- isa<UndefValue>(IElt->getOperand(0))) {
- ArrayRef<int> Mask = Shuf->getShuffleMask();
- Constant *SplatVal = IElt->getOperand(1);
- ConstantInt *Index = dyn_cast<ConstantInt>(IElt->getOperand(2));
- if (Index && Index->getValue() == 0 &&
- llvm::all_of(Mask, [](int I) { return I == 0; }))
- return SplatVal;
- }
- }
- return nullptr;
- }
- Constant *ConstantVector::getSplatValue(bool AllowUndefs) const {
- // Check out first element.
- Constant *Elt = getOperand(0);
- // Then make sure all remaining elements point to the same value.
- for (unsigned I = 1, E = getNumOperands(); I < E; ++I) {
- Constant *OpC = getOperand(I);
- if (OpC == Elt)
- continue;
- // Strict mode: any mismatch is not a splat.
- if (!AllowUndefs)
- return nullptr;
- // Allow undefs mode: ignore undefined elements.
- if (isa<UndefValue>(OpC))
- continue;
- // If we do not have a defined element yet, use the current operand.
- if (isa<UndefValue>(Elt))
- Elt = OpC;
- if (OpC != Elt)
- return nullptr;
- }
- return Elt;
- }
- const APInt &Constant::getUniqueInteger() const {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
- return CI->getValue();
- assert(this->getSplatValue() && "Doesn't contain a unique integer!");
- const Constant *C = this->getAggregateElement(0U);
- assert(C && isa<ConstantInt>(C) && "Not a vector of numbers!");
- return cast<ConstantInt>(C)->getValue();
- }
- //---- ConstantPointerNull::get() implementation.
- //
- ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
- std::unique_ptr<ConstantPointerNull> &Entry =
- Ty->getContext().pImpl->CPNConstants[Ty];
- if (!Entry)
- Entry.reset(new ConstantPointerNull(Ty));
- return Entry.get();
- }
- /// Remove the constant from the constant table.
- void ConstantPointerNull::destroyConstantImpl() {
- getContext().pImpl->CPNConstants.erase(getType());
- }
- UndefValue *UndefValue::get(Type *Ty) {
- std::unique_ptr<UndefValue> &Entry = Ty->getContext().pImpl->UVConstants[Ty];
- if (!Entry)
- Entry.reset(new UndefValue(Ty));
- return Entry.get();
- }
- /// Remove the constant from the constant table.
- void UndefValue::destroyConstantImpl() {
- // Free the constant and any dangling references to it.
- if (getValueID() == UndefValueVal) {
- getContext().pImpl->UVConstants.erase(getType());
- } else if (getValueID() == PoisonValueVal) {
- getContext().pImpl->PVConstants.erase(getType());
- }
- llvm_unreachable("Not a undef or a poison!");
- }
- PoisonValue *PoisonValue::get(Type *Ty) {
- std::unique_ptr<PoisonValue> &Entry = Ty->getContext().pImpl->PVConstants[Ty];
- if (!Entry)
- Entry.reset(new PoisonValue(Ty));
- return Entry.get();
- }
- /// Remove the constant from the constant table.
- void PoisonValue::destroyConstantImpl() {
- // Free the constant and any dangling references to it.
- getContext().pImpl->PVConstants.erase(getType());
- }
- BlockAddress *BlockAddress::get(BasicBlock *BB) {
- assert(BB->getParent() && "Block must have a parent");
- return get(BB->getParent(), BB);
- }
- BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
- BlockAddress *&BA =
- F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)];
- if (!BA)
- BA = new BlockAddress(F, BB);
- assert(BA->getFunction() == F && "Basic block moved between functions");
- return BA;
- }
- BlockAddress::BlockAddress(Function *F, BasicBlock *BB)
- : Constant(Type::getInt8PtrTy(F->getContext(), F->getAddressSpace()),
- Value::BlockAddressVal, &Op<0>(), 2) {
- setOperand(0, F);
- setOperand(1, BB);
- BB->AdjustBlockAddressRefCount(1);
- }
- BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
- if (!BB->hasAddressTaken())
- return nullptr;
- const Function *F = BB->getParent();
- assert(F && "Block must have a parent");
- BlockAddress *BA =
- F->getContext().pImpl->BlockAddresses.lookup(std::make_pair(F, BB));
- assert(BA && "Refcount and block address map disagree!");
- return BA;
- }
- /// Remove the constant from the constant table.
- void BlockAddress::destroyConstantImpl() {
- getFunction()->getType()->getContext().pImpl
- ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock()));
- getBasicBlock()->AdjustBlockAddressRefCount(-1);
- }
- Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) {
- // This could be replacing either the Basic Block or the Function. In either
- // case, we have to remove the map entry.
- Function *NewF = getFunction();
- BasicBlock *NewBB = getBasicBlock();
- if (From == NewF)
- NewF = cast<Function>(To->stripPointerCasts());
- else {
- assert(From == NewBB && "From does not match any operand");
- NewBB = cast<BasicBlock>(To);
- }
- // See if the 'new' entry already exists, if not, just update this in place
- // and return early.
- BlockAddress *&NewBA =
- getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)];
- if (NewBA)
- return NewBA;
- getBasicBlock()->AdjustBlockAddressRefCount(-1);
- // Remove the old entry, this can't cause the map to rehash (just a
- // tombstone will get added).
- getContext().pImpl->BlockAddresses.erase(std::make_pair(getFunction(),
- getBasicBlock()));
- NewBA = this;
- setOperand(0, NewF);
- setOperand(1, NewBB);
- getBasicBlock()->AdjustBlockAddressRefCount(1);
- // If we just want to keep the existing value, then return null.
- // Callers know that this means we shouldn't delete this value.
- return nullptr;
- }
- DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
- DSOLocalEquivalent *&Equiv = GV->getContext().pImpl->DSOLocalEquivalents[GV];
- if (!Equiv)
- Equiv = new DSOLocalEquivalent(GV);
- assert(Equiv->getGlobalValue() == GV &&
- "DSOLocalFunction does not match the expected global value");
- return Equiv;
- }
- DSOLocalEquivalent::DSOLocalEquivalent(GlobalValue *GV)
- : Constant(GV->getType(), Value::DSOLocalEquivalentVal, &Op<0>(), 1) {
- setOperand(0, GV);
- }
- /// Remove the constant from the constant table.
- void DSOLocalEquivalent::destroyConstantImpl() {
- const GlobalValue *GV = getGlobalValue();
- GV->getContext().pImpl->DSOLocalEquivalents.erase(GV);
- }
- Value *DSOLocalEquivalent::handleOperandChangeImpl(Value *From, Value *To) {
- assert(From == getGlobalValue() && "Changing value does not match operand.");
- assert(isa<Constant>(To) && "Can only replace the operands with a constant");
- // The replacement is with another global value.
- if (const auto *ToObj = dyn_cast<GlobalValue>(To)) {
- DSOLocalEquivalent *&NewEquiv =
- getContext().pImpl->DSOLocalEquivalents[ToObj];
- if (NewEquiv)
- return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
- }
- // If the argument is replaced with a null value, just replace this constant
- // with a null value.
- if (cast<Constant>(To)->isNullValue())
- return To;
- // The replacement could be a bitcast or an alias to another function. We can
- // replace it with a bitcast to the dso_local_equivalent of that function.
- auto *Func = cast<Function>(To->stripPointerCastsAndAliases());
- DSOLocalEquivalent *&NewEquiv = getContext().pImpl->DSOLocalEquivalents[Func];
- if (NewEquiv)
- return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
- // Replace this with the new one.
- getContext().pImpl->DSOLocalEquivalents.erase(getGlobalValue());
- NewEquiv = this;
- setOperand(0, Func);
- if (Func->getType() != getType()) {
- // It is ok to mutate the type here because this constant should always
- // reflect the type of the function it's holding.
- mutateType(Func->getType());
- }
- return nullptr;
- }
- NoCFIValue *NoCFIValue::get(GlobalValue *GV) {
- NoCFIValue *&NC = GV->getContext().pImpl->NoCFIValues[GV];
- if (!NC)
- NC = new NoCFIValue(GV);
- assert(NC->getGlobalValue() == GV &&
- "NoCFIValue does not match the expected global value");
- return NC;
- }
- NoCFIValue::NoCFIValue(GlobalValue *GV)
- : Constant(GV->getType(), Value::NoCFIValueVal, &Op<0>(), 1) {
- setOperand(0, GV);
- }
- /// Remove the constant from the constant table.
- void NoCFIValue::destroyConstantImpl() {
- const GlobalValue *GV = getGlobalValue();
- GV->getContext().pImpl->NoCFIValues.erase(GV);
- }
- Value *NoCFIValue::handleOperandChangeImpl(Value *From, Value *To) {
- assert(From == getGlobalValue() && "Changing value does not match operand.");
- GlobalValue *GV = dyn_cast<GlobalValue>(To->stripPointerCasts());
- assert(GV && "Can only replace the operands with a global value");
- NoCFIValue *&NewNC = getContext().pImpl->NoCFIValues[GV];
- if (NewNC)
- return llvm::ConstantExpr::getBitCast(NewNC, getType());
- getContext().pImpl->NoCFIValues.erase(getGlobalValue());
- NewNC = this;
- setOperand(0, GV);
- if (GV->getType() != getType())
- mutateType(GV->getType());
- return nullptr;
- }
- //---- ConstantExpr::get() implementations.
- //
- /// This is a utility function to handle folding of casts and lookup of the
- /// cast in the ExprConstants map. It is used by the various get* methods below.
- static Constant *getFoldedCast(Instruction::CastOps opc, Constant *C, Type *Ty,
- bool OnlyIfReduced = false) {
- assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
- // Fold a few common cases
- if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty))
- return FC;
- if (OnlyIfReduced)
- return nullptr;
- LLVMContextImpl *pImpl = Ty->getContext().pImpl;
- // Look up the constant in the table first to ensure uniqueness.
- ConstantExprKeyType Key(opc, C);
- return pImpl->ExprConstants.getOrCreate(Ty, Key);
- }
- Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty,
- bool OnlyIfReduced) {
- Instruction::CastOps opc = Instruction::CastOps(oc);
- assert(Instruction::isCast(opc) && "opcode out of range");
- assert(C && Ty && "Null arguments to getCast");
- assert(CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!");
- switch (opc) {
- default:
- llvm_unreachable("Invalid cast opcode");
- case Instruction::Trunc:
- return getTrunc(C, Ty, OnlyIfReduced);
- case Instruction::ZExt:
- return getZExt(C, Ty, OnlyIfReduced);
- case Instruction::SExt:
- return getSExt(C, Ty, OnlyIfReduced);
- case Instruction::FPTrunc:
- return getFPTrunc(C, Ty, OnlyIfReduced);
- case Instruction::FPExt:
- return getFPExtend(C, Ty, OnlyIfReduced);
- case Instruction::UIToFP:
- return getUIToFP(C, Ty, OnlyIfReduced);
- case Instruction::SIToFP:
- return getSIToFP(C, Ty, OnlyIfReduced);
- case Instruction::FPToUI:
- return getFPToUI(C, Ty, OnlyIfReduced);
- case Instruction::FPToSI:
- return getFPToSI(C, Ty, OnlyIfReduced);
- case Instruction::PtrToInt:
- return getPtrToInt(C, Ty, OnlyIfReduced);
- case Instruction::IntToPtr:
- return getIntToPtr(C, Ty, OnlyIfReduced);
- case Instruction::BitCast:
- return getBitCast(C, Ty, OnlyIfReduced);
- case Instruction::AddrSpaceCast:
- return getAddrSpaceCast(C, Ty, OnlyIfReduced);
- }
- }
- Constant *ConstantExpr::getZExtOrBitCast(Constant *C, Type *Ty) {
- if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getBitCast(C, Ty);
- return getZExt(C, Ty);
- }
- Constant *ConstantExpr::getSExtOrBitCast(Constant *C, Type *Ty) {
- if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getBitCast(C, Ty);
- return getSExt(C, Ty);
- }
- Constant *ConstantExpr::getTruncOrBitCast(Constant *C, Type *Ty) {
- if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getBitCast(C, Ty);
- return getTrunc(C, Ty);
- }
- Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) {
- assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
- assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) &&
- "Invalid cast");
- if (Ty->isIntOrIntVectorTy())
- return getPtrToInt(S, Ty);
- unsigned SrcAS = S->getType()->getPointerAddressSpace();
- if (Ty->isPtrOrPtrVectorTy() && SrcAS != Ty->getPointerAddressSpace())
- return getAddrSpaceCast(S, Ty);
- return getBitCast(S, Ty);
- }
- Constant *ConstantExpr::getPointerBitCastOrAddrSpaceCast(Constant *S,
- Type *Ty) {
- assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
- assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast");
- if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace())
- return getAddrSpaceCast(S, Ty);
- return getBitCast(S, Ty);
- }
- Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, bool isSigned) {
- assert(C->getType()->isIntOrIntVectorTy() &&
- Ty->isIntOrIntVectorTy() && "Invalid cast");
- unsigned SrcBits = C->getType()->getScalarSizeInBits();
- unsigned DstBits = Ty->getScalarSizeInBits();
- Instruction::CastOps opcode =
- (SrcBits == DstBits ? Instruction::BitCast :
- (SrcBits > DstBits ? Instruction::Trunc :
- (isSigned ? Instruction::SExt : Instruction::ZExt)));
- return getCast(opcode, C, Ty);
- }
- Constant *ConstantExpr::getFPCast(Constant *C, Type *Ty) {
- assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
- "Invalid cast");
- unsigned SrcBits = C->getType()->getScalarSizeInBits();
- unsigned DstBits = Ty->getScalarSizeInBits();
- if (SrcBits == DstBits)
- return C; // Avoid a useless cast
- Instruction::CastOps opcode =
- (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt);
- return getCast(opcode, C, Ty);
- }
- Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVectorTy() && "Trunc operand must be integer");
- assert(Ty->isIntOrIntVectorTy() && "Trunc produces only integral");
- assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
- "SrcTy must be larger than DestTy for Trunc!");
- return getFoldedCast(Instruction::Trunc, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getSExt(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVectorTy() && "SExt operand must be integral");
- assert(Ty->isIntOrIntVectorTy() && "SExt produces only integer");
- assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
- "SrcTy must be smaller than DestTy for SExt!");
- return getFoldedCast(Instruction::SExt, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getZExt(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVectorTy() && "ZEXt operand must be integral");
- assert(Ty->isIntOrIntVectorTy() && "ZExt produces only integer");
- assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
- "SrcTy must be smaller than DestTy for ZExt!");
- return getFoldedCast(Instruction::ZExt, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getFPTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
- C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
- "This is an illegal floating point truncation!");
- return getFoldedCast(Instruction::FPTrunc, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getFPExtend(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
- C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
- "This is an illegal floating point extension!");
- return getFoldedCast(Instruction::FPExt, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getUIToFP(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
- "This is an illegal uint to floating point cast!");
- return getFoldedCast(Instruction::UIToFP, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getSIToFP(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
- "This is an illegal sint to floating point cast!");
- return getFoldedCast(Instruction::SIToFP, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getFPToUI(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
- "This is an illegal floating point to uint cast!");
- return getFoldedCast(Instruction::FPToUI, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getFPToSI(Constant *C, Type *Ty, bool OnlyIfReduced) {
- #ifndef NDEBUG
- bool fromVec = isa<VectorType>(C->getType());
- bool toVec = isa<VectorType>(Ty);
- #endif
- assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
- "This is an illegal floating point to sint cast!");
- return getFoldedCast(Instruction::FPToSI, C, Ty, OnlyIfReduced);
- }
- Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy,
- bool OnlyIfReduced) {
- assert(C->getType()->isPtrOrPtrVectorTy() &&
- "PtrToInt source must be pointer or pointer vector");
- assert(DstTy->isIntOrIntVectorTy() &&
- "PtrToInt destination must be integer or integer vector");
- assert(isa<VectorType>(C->getType()) == isa<VectorType>(DstTy));
- if (isa<VectorType>(C->getType()))
- assert(cast<FixedVectorType>(C->getType())->getNumElements() ==
- cast<FixedVectorType>(DstTy)->getNumElements() &&
- "Invalid cast between a different number of vector elements");
- return getFoldedCast(Instruction::PtrToInt, C, DstTy, OnlyIfReduced);
- }
- Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy,
- bool OnlyIfReduced) {
- assert(C->getType()->isIntOrIntVectorTy() &&
- "IntToPtr source must be integer or integer vector");
- assert(DstTy->isPtrOrPtrVectorTy() &&
- "IntToPtr destination must be a pointer or pointer vector");
- assert(isa<VectorType>(C->getType()) == isa<VectorType>(DstTy));
- if (isa<VectorType>(C->getType()))
- assert(cast<VectorType>(C->getType())->getElementCount() ==
- cast<VectorType>(DstTy)->getElementCount() &&
- "Invalid cast between a different number of vector elements");
- return getFoldedCast(Instruction::IntToPtr, C, DstTy, OnlyIfReduced);
- }
- Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy,
- bool OnlyIfReduced) {
- assert(CastInst::castIsValid(Instruction::BitCast, C, DstTy) &&
- "Invalid constantexpr bitcast!");
- // It is common to ask for a bitcast of a value to its own type, handle this
- // speedily.
- if (C->getType() == DstTy) return C;
- return getFoldedCast(Instruction::BitCast, C, DstTy, OnlyIfReduced);
- }
- Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy,
- bool OnlyIfReduced) {
- assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) &&
- "Invalid constantexpr addrspacecast!");
- // Canonicalize addrspacecasts between different pointer types by first
- // bitcasting the pointer type and then converting the address space.
- PointerType *SrcScalarTy = cast<PointerType>(C->getType()->getScalarType());
- PointerType *DstScalarTy = cast<PointerType>(DstTy->getScalarType());
- if (!SrcScalarTy->hasSameElementTypeAs(DstScalarTy)) {
- Type *MidTy = PointerType::getWithSamePointeeType(
- DstScalarTy, SrcScalarTy->getAddressSpace());
- if (VectorType *VT = dyn_cast<VectorType>(DstTy)) {
- // Handle vectors of pointers.
- MidTy = FixedVectorType::get(MidTy,
- cast<FixedVectorType>(VT)->getNumElements());
- }
- C = getBitCast(C, MidTy);
- }
- return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy, OnlyIfReduced);
- }
- Constant *ConstantExpr::get(unsigned Opcode, Constant *C, unsigned Flags,
- Type *OnlyIfReducedTy) {
- // Check the operands for consistency first.
- assert(Instruction::isUnaryOp(Opcode) &&
- "Invalid opcode in unary constant expression");
- #ifndef NDEBUG
- switch (Opcode) {
- case Instruction::FNeg:
- assert(C->getType()->isFPOrFPVectorTy() &&
- "Tried to create a floating-point operation on a "
- "non-floating-point type!");
- break;
- default:
- break;
- }
- #endif
- if (Constant *FC = ConstantFoldUnaryInstruction(Opcode, C))
- return FC;
- if (OnlyIfReducedTy == C->getType())
- return nullptr;
- Constant *ArgVec[] = { C };
- ConstantExprKeyType Key(Opcode, ArgVec, 0, Flags);
- LLVMContextImpl *pImpl = C->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(C->getType(), Key);
- }
- Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
- unsigned Flags, Type *OnlyIfReducedTy) {
- // Check the operands for consistency first.
- assert(Instruction::isBinaryOp(Opcode) &&
- "Invalid opcode in binary constant expression");
- assert(C1->getType() == C2->getType() &&
- "Operand types in binary constant expression should match");
- #ifndef NDEBUG
- switch (Opcode) {
- case Instruction::Add:
- case Instruction::Sub:
- case Instruction::Mul:
- case Instruction::UDiv:
- case Instruction::SDiv:
- case Instruction::URem:
- case Instruction::SRem:
- assert(C1->getType()->isIntOrIntVectorTy() &&
- "Tried to create an integer operation on a non-integer type!");
- break;
- case Instruction::FAdd:
- case Instruction::FSub:
- case Instruction::FMul:
- case Instruction::FDiv:
- case Instruction::FRem:
- assert(C1->getType()->isFPOrFPVectorTy() &&
- "Tried to create a floating-point operation on a "
- "non-floating-point type!");
- break;
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- assert(C1->getType()->isIntOrIntVectorTy() &&
- "Tried to create a logical operation on a non-integral type!");
- break;
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- assert(C1->getType()->isIntOrIntVectorTy() &&
- "Tried to create a shift operation on a non-integer type!");
- break;
- default:
- break;
- }
- #endif
- if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
- return FC;
- if (OnlyIfReducedTy == C1->getType())
- return nullptr;
- Constant *ArgVec[] = { C1, C2 };
- ConstantExprKeyType Key(Opcode, ArgVec, 0, Flags);
- LLVMContextImpl *pImpl = C1->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
- }
- Constant *ConstantExpr::getSizeOf(Type* Ty) {
- // sizeof is implemented as: (i64) gep (Ty*)null, 1
- // Note that a non-inbounds gep is used, as null isn't within any object.
- Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
- Constant *GEP = getGetElementPtr(
- Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
- return getPtrToInt(GEP,
- Type::getInt64Ty(Ty->getContext()));
- }
- Constant *ConstantExpr::getAlignOf(Type* Ty) {
- // alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
- // Note that a non-inbounds gep is used, as null isn't within any object.
- Type *AligningTy = StructType::get(Type::getInt1Ty(Ty->getContext()), Ty);
- Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo(0));
- Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0);
- Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
- Constant *Indices[2] = { Zero, One };
- Constant *GEP = getGetElementPtr(AligningTy, NullPtr, Indices);
- return getPtrToInt(GEP,
- Type::getInt64Ty(Ty->getContext()));
- }
- Constant *ConstantExpr::getOffsetOf(StructType* STy, unsigned FieldNo) {
- return getOffsetOf(STy, ConstantInt::get(Type::getInt32Ty(STy->getContext()),
- FieldNo));
- }
- Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) {
- // offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo
- // Note that a non-inbounds gep is used, as null isn't within any object.
- Constant *GEPIdx[] = {
- ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0),
- FieldNo
- };
- Constant *GEP = getGetElementPtr(
- Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
- return getPtrToInt(GEP,
- Type::getInt64Ty(Ty->getContext()));
- }
- Constant *ConstantExpr::getCompare(unsigned short Predicate, Constant *C1,
- Constant *C2, bool OnlyIfReduced) {
- assert(C1->getType() == C2->getType() && "Op types should be identical!");
- switch (Predicate) {
- default: llvm_unreachable("Invalid CmpInst predicate");
- case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT:
- case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLT: case CmpInst::FCMP_OLE:
- case CmpInst::FCMP_ONE: case CmpInst::FCMP_ORD: case CmpInst::FCMP_UNO:
- case CmpInst::FCMP_UEQ: case CmpInst::FCMP_UGT: case CmpInst::FCMP_UGE:
- case CmpInst::FCMP_ULT: case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE:
- case CmpInst::FCMP_TRUE:
- return getFCmp(Predicate, C1, C2, OnlyIfReduced);
- case CmpInst::ICMP_EQ: case CmpInst::ICMP_NE: case CmpInst::ICMP_UGT:
- case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE:
- case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT:
- case CmpInst::ICMP_SLE:
- return getICmp(Predicate, C1, C2, OnlyIfReduced);
- }
- }
- Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2,
- Type *OnlyIfReducedTy) {
- assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands");
- if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2))
- return SC; // Fold common cases
- if (OnlyIfReducedTy == V1->getType())
- return nullptr;
- Constant *ArgVec[] = { C, V1, V2 };
- ConstantExprKeyType Key(Instruction::Select, ArgVec);
- LLVMContextImpl *pImpl = C->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
- }
- Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> Idxs, bool InBounds,
- Optional<unsigned> InRangeIndex,
- Type *OnlyIfReducedTy) {
- PointerType *OrigPtrTy = cast<PointerType>(C->getType()->getScalarType());
- assert(Ty && "Must specify element type");
- assert(OrigPtrTy->isOpaqueOrPointeeTypeMatches(Ty));
- if (Constant *FC =
- ConstantFoldGetElementPtr(Ty, C, InBounds, InRangeIndex, Idxs))
- return FC; // Fold a few common cases.
- // Get the result type of the getelementptr!
- Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs);
- assert(DestTy && "GEP indices invalid!");
- unsigned AS = OrigPtrTy->getAddressSpace();
- Type *ReqTy = OrigPtrTy->isOpaque()
- ? PointerType::get(OrigPtrTy->getContext(), AS)
- : DestTy->getPointerTo(AS);
- auto EltCount = ElementCount::getFixed(0);
- if (VectorType *VecTy = dyn_cast<VectorType>(C->getType()))
- EltCount = VecTy->getElementCount();
- else
- for (auto Idx : Idxs)
- if (VectorType *VecTy = dyn_cast<VectorType>(Idx->getType()))
- EltCount = VecTy->getElementCount();
- if (EltCount.isNonZero())
- ReqTy = VectorType::get(ReqTy, EltCount);
- if (OnlyIfReducedTy == ReqTy)
- return nullptr;
- // Look up the constant in the table first to ensure uniqueness
- std::vector<Constant*> ArgVec;
- ArgVec.reserve(1 + Idxs.size());
- ArgVec.push_back(C);
- auto GTI = gep_type_begin(Ty, Idxs), GTE = gep_type_end(Ty, Idxs);
- for (; GTI != GTE; ++GTI) {
- auto *Idx = cast<Constant>(GTI.getOperand());
- assert(
- (!isa<VectorType>(Idx->getType()) ||
- cast<VectorType>(Idx->getType())->getElementCount() == EltCount) &&
- "getelementptr index type missmatch");
- if (GTI.isStruct() && Idx->getType()->isVectorTy()) {
- Idx = Idx->getSplatValue();
- } else if (GTI.isSequential() && EltCount.isNonZero() &&
- !Idx->getType()->isVectorTy()) {
- Idx = ConstantVector::getSplat(EltCount, Idx);
- }
- ArgVec.push_back(Idx);
- }
- unsigned SubClassOptionalData = InBounds ? GEPOperator::IsInBounds : 0;
- if (InRangeIndex && *InRangeIndex < 63)
- SubClassOptionalData |= (*InRangeIndex + 1) << 1;
- const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
- SubClassOptionalData, None, None, Ty);
- LLVMContextImpl *pImpl = C->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
- }
- Constant *ConstantExpr::getICmp(unsigned short pred, Constant *LHS,
- Constant *RHS, bool OnlyIfReduced) {
- auto Predicate = static_cast<CmpInst::Predicate>(pred);
- assert(LHS->getType() == RHS->getType());
- assert(CmpInst::isIntPredicate(Predicate) && "Invalid ICmp Predicate");
- if (Constant *FC = ConstantFoldCompareInstruction(Predicate, LHS, RHS))
- return FC; // Fold a few common cases...
- if (OnlyIfReduced)
- return nullptr;
- // Look up the constant in the table first to ensure uniqueness
- Constant *ArgVec[] = { LHS, RHS };
- // Get the key type with both the opcode and predicate
- const ConstantExprKeyType Key(Instruction::ICmp, ArgVec, Predicate);
- Type *ResultTy = Type::getInt1Ty(LHS->getContext());
- if (VectorType *VT = dyn_cast<VectorType>(LHS->getType()))
- ResultTy = VectorType::get(ResultTy, VT->getElementCount());
- LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ResultTy, Key);
- }
- Constant *ConstantExpr::getFCmp(unsigned short pred, Constant *LHS,
- Constant *RHS, bool OnlyIfReduced) {
- auto Predicate = static_cast<CmpInst::Predicate>(pred);
- assert(LHS->getType() == RHS->getType());
- assert(CmpInst::isFPPredicate(Predicate) && "Invalid FCmp Predicate");
- if (Constant *FC = ConstantFoldCompareInstruction(Predicate, LHS, RHS))
- return FC; // Fold a few common cases...
- if (OnlyIfReduced)
- return nullptr;
- // Look up the constant in the table first to ensure uniqueness
- Constant *ArgVec[] = { LHS, RHS };
- // Get the key type with both the opcode and predicate
- const ConstantExprKeyType Key(Instruction::FCmp, ArgVec, Predicate);
- Type *ResultTy = Type::getInt1Ty(LHS->getContext());
- if (VectorType *VT = dyn_cast<VectorType>(LHS->getType()))
- ResultTy = VectorType::get(ResultTy, VT->getElementCount());
- LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ResultTy, Key);
- }
- Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx,
- Type *OnlyIfReducedTy) {
- assert(Val->getType()->isVectorTy() &&
- "Tried to create extractelement operation on non-vector type!");
- assert(Idx->getType()->isIntegerTy() &&
- "Extractelement index must be an integer type!");
- if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
- return FC; // Fold a few common cases.
- Type *ReqTy = cast<VectorType>(Val->getType())->getElementType();
- if (OnlyIfReducedTy == ReqTy)
- return nullptr;
- // Look up the constant in the table first to ensure uniqueness
- Constant *ArgVec[] = { Val, Idx };
- const ConstantExprKeyType Key(Instruction::ExtractElement, ArgVec);
- LLVMContextImpl *pImpl = Val->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
- }
- Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
- Constant *Idx, Type *OnlyIfReducedTy) {
- assert(Val->getType()->isVectorTy() &&
- "Tried to create insertelement operation on non-vector type!");
- assert(Elt->getType() == cast<VectorType>(Val->getType())->getElementType() &&
- "Insertelement types must match!");
- assert(Idx->getType()->isIntegerTy() &&
- "Insertelement index must be i32 type!");
- if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
- return FC; // Fold a few common cases.
- if (OnlyIfReducedTy == Val->getType())
- return nullptr;
- // Look up the constant in the table first to ensure uniqueness
- Constant *ArgVec[] = { Val, Elt, Idx };
- const ConstantExprKeyType Key(Instruction::InsertElement, ArgVec);
- LLVMContextImpl *pImpl = Val->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(Val->getType(), Key);
- }
- Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
- ArrayRef<int> Mask,
- Type *OnlyIfReducedTy) {
- assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) &&
- "Invalid shuffle vector constant expr operands!");
- if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask))
- return FC; // Fold a few common cases.
- unsigned NElts = Mask.size();
- auto V1VTy = cast<VectorType>(V1->getType());
- Type *EltTy = V1VTy->getElementType();
- bool TypeIsScalable = isa<ScalableVectorType>(V1VTy);
- Type *ShufTy = VectorType::get(EltTy, NElts, TypeIsScalable);
- if (OnlyIfReducedTy == ShufTy)
- return nullptr;
- // Look up the constant in the table first to ensure uniqueness
- Constant *ArgVec[] = {V1, V2};
- ConstantExprKeyType Key(Instruction::ShuffleVector, ArgVec, 0, 0, None, Mask);
- LLVMContextImpl *pImpl = ShufTy->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ShufTy, Key);
- }
- Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> Idxs,
- Type *OnlyIfReducedTy) {
- assert(Agg->getType()->isFirstClassType() &&
- "Non-first-class type for constant insertvalue expression");
- assert(ExtractValueInst::getIndexedType(Agg->getType(),
- Idxs) == Val->getType() &&
- "insertvalue indices invalid!");
- Type *ReqTy = Val->getType();
- if (Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs))
- return FC;
- if (OnlyIfReducedTy == ReqTy)
- return nullptr;
- Constant *ArgVec[] = { Agg, Val };
- const ConstantExprKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, Idxs);
- LLVMContextImpl *pImpl = Agg->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
- }
- Constant *ConstantExpr::getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs,
- Type *OnlyIfReducedTy) {
- assert(Agg->getType()->isFirstClassType() &&
- "Tried to create extractelement operation on non-first-class type!");
- Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs);
- (void)ReqTy;
- assert(ReqTy && "extractvalue indices invalid!");
- assert(Agg->getType()->isFirstClassType() &&
- "Non-first-class type for constant extractvalue expression");
- if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs))
- return FC;
- if (OnlyIfReducedTy == ReqTy)
- return nullptr;
- Constant *ArgVec[] = { Agg };
- const ConstantExprKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs);
- LLVMContextImpl *pImpl = Agg->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
- }
- Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) {
- assert(C->getType()->isIntOrIntVectorTy() &&
- "Cannot NEG a nonintegral value!");
- return getSub(ConstantFP::getZeroValueForNegation(C->getType()),
- C, HasNUW, HasNSW);
- }
- Constant *ConstantExpr::getFNeg(Constant *C) {
- assert(C->getType()->isFPOrFPVectorTy() &&
- "Cannot FNEG a non-floating-point value!");
- return get(Instruction::FNeg, C);
- }
- Constant *ConstantExpr::getNot(Constant *C) {
- assert(C->getType()->isIntOrIntVectorTy() &&
- "Cannot NOT a nonintegral value!");
- return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()));
- }
- Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2,
- bool HasNUW, bool HasNSW) {
- unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
- (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0);
- return get(Instruction::Add, C1, C2, Flags);
- }
- Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) {
- return get(Instruction::FAdd, C1, C2);
- }
- Constant *ConstantExpr::getSub(Constant *C1, Constant *C2,
- bool HasNUW, bool HasNSW) {
- unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
- (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0);
- return get(Instruction::Sub, C1, C2, Flags);
- }
- Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) {
- return get(Instruction::FSub, C1, C2);
- }
- Constant *ConstantExpr::getMul(Constant *C1, Constant *C2,
- bool HasNUW, bool HasNSW) {
- unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
- (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0);
- return get(Instruction::Mul, C1, C2, Flags);
- }
- Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) {
- return get(Instruction::FMul, C1, C2);
- }
- Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact) {
- return get(Instruction::UDiv, C1, C2,
- isExact ? PossiblyExactOperator::IsExact : 0);
- }
- Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact) {
- return get(Instruction::SDiv, C1, C2,
- isExact ? PossiblyExactOperator::IsExact : 0);
- }
- Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) {
- return get(Instruction::FDiv, C1, C2);
- }
- Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) {
- return get(Instruction::URem, C1, C2);
- }
- Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) {
- return get(Instruction::SRem, C1, C2);
- }
- Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) {
- return get(Instruction::FRem, C1, C2);
- }
- Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) {
- return get(Instruction::And, C1, C2);
- }
- Constant *ConstantExpr::getOr(Constant *C1, Constant *C2) {
- return get(Instruction::Or, C1, C2);
- }
- Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
- return get(Instruction::Xor, C1, C2);
- }
- Constant *ConstantExpr::getUMin(Constant *C1, Constant *C2) {
- Constant *Cmp = ConstantExpr::getICmp(CmpInst::ICMP_ULT, C1, C2);
- return getSelect(Cmp, C1, C2);
- }
- Constant *ConstantExpr::getShl(Constant *C1, Constant *C2,
- bool HasNUW, bool HasNSW) {
- unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
- (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0);
- return get(Instruction::Shl, C1, C2, Flags);
- }
- Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2, bool isExact) {
- return get(Instruction::LShr, C1, C2,
- isExact ? PossiblyExactOperator::IsExact : 0);
- }
- Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
- return get(Instruction::AShr, C1, C2,
- isExact ? PossiblyExactOperator::IsExact : 0);
- }
- Constant *ConstantExpr::getExactLogBase2(Constant *C) {
- Type *Ty = C->getType();
- const APInt *IVal;
- if (match(C, m_APInt(IVal)) && IVal->isPowerOf2())
- return ConstantInt::get(Ty, IVal->logBase2());
- // FIXME: We can extract pow of 2 of splat constant for scalable vectors.
- auto *VecTy = dyn_cast<FixedVectorType>(Ty);
- if (!VecTy)
- return nullptr;
- SmallVector<Constant *, 4> Elts;
- for (unsigned I = 0, E = VecTy->getNumElements(); I != E; ++I) {
- Constant *Elt = C->getAggregateElement(I);
- if (!Elt)
- return nullptr;
- // Note that log2(iN undef) is *NOT* iN undef, because log2(iN undef) u< N.
- if (isa<UndefValue>(Elt)) {
- Elts.push_back(Constant::getNullValue(Ty->getScalarType()));
- continue;
- }
- if (!match(Elt, m_APInt(IVal)) || !IVal->isPowerOf2())
- return nullptr;
- Elts.push_back(ConstantInt::get(Ty->getScalarType(), IVal->logBase2()));
- }
- return ConstantVector::get(Elts);
- }
- Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty,
- bool AllowRHSConstant) {
- assert(Instruction::isBinaryOp(Opcode) && "Only binops allowed");
- // Commutative opcodes: it does not matter if AllowRHSConstant is set.
- if (Instruction::isCommutative(Opcode)) {
- switch (Opcode) {
- case Instruction::Add: // X + 0 = X
- case Instruction::Or: // X | 0 = X
- case Instruction::Xor: // X ^ 0 = X
- return Constant::getNullValue(Ty);
- case Instruction::Mul: // X * 1 = X
- return ConstantInt::get(Ty, 1);
- case Instruction::And: // X & -1 = X
- return Constant::getAllOnesValue(Ty);
- case Instruction::FAdd: // X + -0.0 = X
- // TODO: If the fadd has 'nsz', should we return +0.0?
- return ConstantFP::getNegativeZero(Ty);
- case Instruction::FMul: // X * 1.0 = X
- return ConstantFP::get(Ty, 1.0);
- default:
- llvm_unreachable("Every commutative binop has an identity constant");
- }
- }
- // Non-commutative opcodes: AllowRHSConstant must be set.
- if (!AllowRHSConstant)
- return nullptr;
- switch (Opcode) {
- case Instruction::Sub: // X - 0 = X
- case Instruction::Shl: // X << 0 = X
- case Instruction::LShr: // X >>u 0 = X
- case Instruction::AShr: // X >> 0 = X
- case Instruction::FSub: // X - 0.0 = X
- return Constant::getNullValue(Ty);
- case Instruction::SDiv: // X / 1 = X
- case Instruction::UDiv: // X /u 1 = X
- return ConstantInt::get(Ty, 1);
- case Instruction::FDiv: // X / 1.0 = X
- return ConstantFP::get(Ty, 1.0);
- default:
- return nullptr;
- }
- }
- Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) {
- switch (Opcode) {
- default:
- // Doesn't have an absorber.
- return nullptr;
- case Instruction::Or:
- return Constant::getAllOnesValue(Ty);
- case Instruction::And:
- case Instruction::Mul:
- return Constant::getNullValue(Ty);
- }
- }
- /// Remove the constant from the constant table.
- void ConstantExpr::destroyConstantImpl() {
- getType()->getContext().pImpl->ExprConstants.remove(this);
- }
- const char *ConstantExpr::getOpcodeName() const {
- return Instruction::getOpcodeName(getOpcode());
- }
- GetElementPtrConstantExpr::GetElementPtrConstantExpr(
- Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, Type *DestTy)
- : ConstantExpr(DestTy, Instruction::GetElementPtr,
- OperandTraits<GetElementPtrConstantExpr>::op_end(this) -
- (IdxList.size() + 1),
- IdxList.size() + 1),
- SrcElementTy(SrcElementTy),
- ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)) {
- Op<0>() = C;
- Use *OperandList = getOperandList();
- for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
- OperandList[i+1] = IdxList[i];
- }
- Type *GetElementPtrConstantExpr::getSourceElementType() const {
- return SrcElementTy;
- }
- Type *GetElementPtrConstantExpr::getResultElementType() const {
- return ResElementTy;
- }
- //===----------------------------------------------------------------------===//
- // ConstantData* implementations
- Type *ConstantDataSequential::getElementType() const {
- if (ArrayType *ATy = dyn_cast<ArrayType>(getType()))
- return ATy->getElementType();
- return cast<VectorType>(getType())->getElementType();
- }
- StringRef ConstantDataSequential::getRawDataValues() const {
- return StringRef(DataElements, getNumElements()*getElementByteSize());
- }
- bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) {
- if (Ty->isHalfTy() || Ty->isBFloatTy() || Ty->isFloatTy() || Ty->isDoubleTy())
- return true;
- if (auto *IT = dyn_cast<IntegerType>(Ty)) {
- switch (IT->getBitWidth()) {
- case 8:
- case 16:
- case 32:
- case 64:
- return true;
- default: break;
- }
- }
- return false;
- }
- unsigned ConstantDataSequential::getNumElements() const {
- if (ArrayType *AT = dyn_cast<ArrayType>(getType()))
- return AT->getNumElements();
- return cast<FixedVectorType>(getType())->getNumElements();
- }
- uint64_t ConstantDataSequential::getElementByteSize() const {
- return getElementType()->getPrimitiveSizeInBits()/8;
- }
- /// Return the start of the specified element.
- const char *ConstantDataSequential::getElementPointer(unsigned Elt) const {
- assert(Elt < getNumElements() && "Invalid Elt");
- return DataElements+Elt*getElementByteSize();
- }
- /// Return true if the array is empty or all zeros.
- static bool isAllZeros(StringRef Arr) {
- for (char I : Arr)
- if (I != 0)
- return false;
- return true;
- }
- /// This is the underlying implementation of all of the
- /// ConstantDataSequential::get methods. They all thunk down to here, providing
- /// the correct element type. We take the bytes in as a StringRef because
- /// we *want* an underlying "char*" to avoid TBAA type punning violations.
- Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) {
- #ifndef NDEBUG
- if (ArrayType *ATy = dyn_cast<ArrayType>(Ty))
- assert(isElementTypeCompatible(ATy->getElementType()));
- else
- assert(isElementTypeCompatible(cast<VectorType>(Ty)->getElementType()));
- #endif
- // If the elements are all zero or there are no elements, return a CAZ, which
- // is more dense and canonical.
- if (isAllZeros(Elements))
- return ConstantAggregateZero::get(Ty);
- // Do a lookup to see if we have already formed one of these.
- auto &Slot =
- *Ty->getContext()
- .pImpl->CDSConstants.insert(std::make_pair(Elements, nullptr))
- .first;
- // The bucket can point to a linked list of different CDS's that have the same
- // body but different types. For example, 0,0,0,1 could be a 4 element array
- // of i8, or a 1-element array of i32. They'll both end up in the same
- /// StringMap bucket, linked up by their Next pointers. Walk the list.
- std::unique_ptr<ConstantDataSequential> *Entry = &Slot.second;
- for (; *Entry; Entry = &(*Entry)->Next)
- if ((*Entry)->getType() == Ty)
- return Entry->get();
- // Okay, we didn't get a hit. Create a node of the right class, link it in,
- // and return it.
- if (isa<ArrayType>(Ty)) {
- // Use reset because std::make_unique can't access the constructor.
- Entry->reset(new ConstantDataArray(Ty, Slot.first().data()));
- return Entry->get();
- }
- assert(isa<VectorType>(Ty));
- // Use reset because std::make_unique can't access the constructor.
- Entry->reset(new ConstantDataVector(Ty, Slot.first().data()));
- return Entry->get();
- }
- void ConstantDataSequential::destroyConstantImpl() {
- // Remove the constant from the StringMap.
- StringMap<std::unique_ptr<ConstantDataSequential>> &CDSConstants =
- getType()->getContext().pImpl->CDSConstants;
- auto Slot = CDSConstants.find(getRawDataValues());
- assert(Slot != CDSConstants.end() && "CDS not found in uniquing table");
- std::unique_ptr<ConstantDataSequential> *Entry = &Slot->getValue();
- // Remove the entry from the hash table.
- if (!(*Entry)->Next) {
- // If there is only one value in the bucket (common case) it must be this
- // entry, and removing the entry should remove the bucket completely.
- assert(Entry->get() == this && "Hash mismatch in ConstantDataSequential");
- getContext().pImpl->CDSConstants.erase(Slot);
- return;
- }
- // Otherwise, there are multiple entries linked off the bucket, unlink the
- // node we care about but keep the bucket around.
- while (true) {
- std::unique_ptr<ConstantDataSequential> &Node = *Entry;
- assert(Node && "Didn't find entry in its uniquing hash table!");
- // If we found our entry, unlink it from the list and we're done.
- if (Node.get() == this) {
- Node = std::move(Node->Next);
- return;
- }
- Entry = &Node->Next;
- }
- }
- /// getFP() constructors - Return a constant of array type with a float
- /// element type taken from argument `ElementType', and count taken from
- /// argument `Elts'. The amount of bits of the contained type must match the
- /// number of bits of the type contained in the passed in ArrayRef.
- /// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
- /// that this can return a ConstantAggregateZero object.
- Constant *ConstantDataArray::getFP(Type *ElementType, ArrayRef<uint16_t> Elts) {
- assert((ElementType->isHalfTy() || ElementType->isBFloatTy()) &&
- "Element type is not a 16-bit float type");
- Type *Ty = ArrayType::get(ElementType, Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 2), Ty);
- }
- Constant *ConstantDataArray::getFP(Type *ElementType, ArrayRef<uint32_t> Elts) {
- assert(ElementType->isFloatTy() && "Element type is not a 32-bit float type");
- Type *Ty = ArrayType::get(ElementType, Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 4), Ty);
- }
- Constant *ConstantDataArray::getFP(Type *ElementType, ArrayRef<uint64_t> Elts) {
- assert(ElementType->isDoubleTy() &&
- "Element type is not a 64-bit float type");
- Type *Ty = ArrayType::get(ElementType, Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 8), Ty);
- }
- Constant *ConstantDataArray::getString(LLVMContext &Context,
- StringRef Str, bool AddNull) {
- if (!AddNull) {
- const uint8_t *Data = Str.bytes_begin();
- return get(Context, makeArrayRef(Data, Str.size()));
- }
- SmallVector<uint8_t, 64> ElementVals;
- ElementVals.append(Str.begin(), Str.end());
- ElementVals.push_back(0);
- return get(Context, ElementVals);
- }
- /// get() constructors - Return a constant with vector type with an element
- /// count and element type matching the ArrayRef passed in. Note that this
- /// can return a ConstantAggregateZero object.
- Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint8_t> Elts){
- auto *Ty = FixedVectorType::get(Type::getInt8Ty(Context), Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 1), Ty);
- }
- Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint16_t> Elts){
- auto *Ty = FixedVectorType::get(Type::getInt16Ty(Context), Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 2), Ty);
- }
- Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint32_t> Elts){
- auto *Ty = FixedVectorType::get(Type::getInt32Ty(Context), Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 4), Ty);
- }
- Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint64_t> Elts){
- auto *Ty = FixedVectorType::get(Type::getInt64Ty(Context), Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 8), Ty);
- }
- Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<float> Elts) {
- auto *Ty = FixedVectorType::get(Type::getFloatTy(Context), Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 4), Ty);
- }
- Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<double> Elts) {
- auto *Ty = FixedVectorType::get(Type::getDoubleTy(Context), Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 8), Ty);
- }
- /// getFP() constructors - Return a constant of vector type with a float
- /// element type taken from argument `ElementType', and count taken from
- /// argument `Elts'. The amount of bits of the contained type must match the
- /// number of bits of the type contained in the passed in ArrayRef.
- /// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
- /// that this can return a ConstantAggregateZero object.
- Constant *ConstantDataVector::getFP(Type *ElementType,
- ArrayRef<uint16_t> Elts) {
- assert((ElementType->isHalfTy() || ElementType->isBFloatTy()) &&
- "Element type is not a 16-bit float type");
- auto *Ty = FixedVectorType::get(ElementType, Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 2), Ty);
- }
- Constant *ConstantDataVector::getFP(Type *ElementType,
- ArrayRef<uint32_t> Elts) {
- assert(ElementType->isFloatTy() && "Element type is not a 32-bit float type");
- auto *Ty = FixedVectorType::get(ElementType, Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 4), Ty);
- }
- Constant *ConstantDataVector::getFP(Type *ElementType,
- ArrayRef<uint64_t> Elts) {
- assert(ElementType->isDoubleTy() &&
- "Element type is not a 64-bit float type");
- auto *Ty = FixedVectorType::get(ElementType, Elts.size());
- const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(Data, Elts.size() * 8), Ty);
- }
- Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {
- assert(isElementTypeCompatible(V->getType()) &&
- "Element type not compatible with ConstantData");
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- if (CI->getType()->isIntegerTy(8)) {
- SmallVector<uint8_t, 16> Elts(NumElts, CI->getZExtValue());
- return get(V->getContext(), Elts);
- }
- if (CI->getType()->isIntegerTy(16)) {
- SmallVector<uint16_t, 16> Elts(NumElts, CI->getZExtValue());
- return get(V->getContext(), Elts);
- }
- if (CI->getType()->isIntegerTy(32)) {
- SmallVector<uint32_t, 16> Elts(NumElts, CI->getZExtValue());
- return get(V->getContext(), Elts);
- }
- assert(CI->getType()->isIntegerTy(64) && "Unsupported ConstantData type");
- SmallVector<uint64_t, 16> Elts(NumElts, CI->getZExtValue());
- return get(V->getContext(), Elts);
- }
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
- if (CFP->getType()->isHalfTy()) {
- SmallVector<uint16_t, 16> Elts(
- NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- return getFP(V->getType(), Elts);
- }
- if (CFP->getType()->isBFloatTy()) {
- SmallVector<uint16_t, 16> Elts(
- NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- return getFP(V->getType(), Elts);
- }
- if (CFP->getType()->isFloatTy()) {
- SmallVector<uint32_t, 16> Elts(
- NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- return getFP(V->getType(), Elts);
- }
- if (CFP->getType()->isDoubleTy()) {
- SmallVector<uint64_t, 16> Elts(
- NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
- return getFP(V->getType(), Elts);
- }
- }
- return ConstantVector::getSplat(ElementCount::getFixed(NumElts), V);
- }
- uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const {
- assert(isa<IntegerType>(getElementType()) &&
- "Accessor can only be used when element is an integer");
- const char *EltPtr = getElementPointer(Elt);
- // The data is stored in host byte order, make sure to cast back to the right
- // type to load with the right endianness.
- switch (getElementType()->getIntegerBitWidth()) {
- default: llvm_unreachable("Invalid bitwidth for CDS");
- case 8:
- return *reinterpret_cast<const uint8_t *>(EltPtr);
- case 16:
- return *reinterpret_cast<const uint16_t *>(EltPtr);
- case 32:
- return *reinterpret_cast<const uint32_t *>(EltPtr);
- case 64:
- return *reinterpret_cast<const uint64_t *>(EltPtr);
- }
- }
- APInt ConstantDataSequential::getElementAsAPInt(unsigned Elt) const {
- assert(isa<IntegerType>(getElementType()) &&
- "Accessor can only be used when element is an integer");
- const char *EltPtr = getElementPointer(Elt);
- // The data is stored in host byte order, make sure to cast back to the right
- // type to load with the right endianness.
- switch (getElementType()->getIntegerBitWidth()) {
- default: llvm_unreachable("Invalid bitwidth for CDS");
- case 8: {
- auto EltVal = *reinterpret_cast<const uint8_t *>(EltPtr);
- return APInt(8, EltVal);
- }
- case 16: {
- auto EltVal = *reinterpret_cast<const uint16_t *>(EltPtr);
- return APInt(16, EltVal);
- }
- case 32: {
- auto EltVal = *reinterpret_cast<const uint32_t *>(EltPtr);
- return APInt(32, EltVal);
- }
- case 64: {
- auto EltVal = *reinterpret_cast<const uint64_t *>(EltPtr);
- return APInt(64, EltVal);
- }
- }
- }
- APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
- const char *EltPtr = getElementPointer(Elt);
- switch (getElementType()->getTypeID()) {
- default:
- llvm_unreachable("Accessor can only be used when element is float/double!");
- case Type::HalfTyID: {
- auto EltVal = *reinterpret_cast<const uint16_t *>(EltPtr);
- return APFloat(APFloat::IEEEhalf(), APInt(16, EltVal));
- }
- case Type::BFloatTyID: {
- auto EltVal = *reinterpret_cast<const uint16_t *>(EltPtr);
- return APFloat(APFloat::BFloat(), APInt(16, EltVal));
- }
- case Type::FloatTyID: {
- auto EltVal = *reinterpret_cast<const uint32_t *>(EltPtr);
- return APFloat(APFloat::IEEEsingle(), APInt(32, EltVal));
- }
- case Type::DoubleTyID: {
- auto EltVal = *reinterpret_cast<const uint64_t *>(EltPtr);
- return APFloat(APFloat::IEEEdouble(), APInt(64, EltVal));
- }
- }
- }
- float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
- assert(getElementType()->isFloatTy() &&
- "Accessor can only be used when element is a 'float'");
- return *reinterpret_cast<const float *>(getElementPointer(Elt));
- }
- double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
- assert(getElementType()->isDoubleTy() &&
- "Accessor can only be used when element is a 'float'");
- return *reinterpret_cast<const double *>(getElementPointer(Elt));
- }
- Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
- if (getElementType()->isHalfTy() || getElementType()->isBFloatTy() ||
- getElementType()->isFloatTy() || getElementType()->isDoubleTy())
- return ConstantFP::get(getContext(), getElementAsAPFloat(Elt));
- return ConstantInt::get(getElementType(), getElementAsInteger(Elt));
- }
- bool ConstantDataSequential::isString(unsigned CharSize) const {
- return isa<ArrayType>(getType()) && getElementType()->isIntegerTy(CharSize);
- }
- bool ConstantDataSequential::isCString() const {
- if (!isString())
- return false;
- StringRef Str = getAsString();
- // The last value must be nul.
- if (Str.back() != 0) return false;
- // Other elements must be non-nul.
- return !Str.drop_back().contains(0);
- }
- bool ConstantDataVector::isSplatData() const {
- const char *Base = getRawDataValues().data();
- // Compare elements 1+ to the 0'th element.
- unsigned EltSize = getElementByteSize();
- for (unsigned i = 1, e = getNumElements(); i != e; ++i)
- if (memcmp(Base, Base+i*EltSize, EltSize))
- return false;
- return true;
- }
- bool ConstantDataVector::isSplat() const {
- if (!IsSplatSet) {
- IsSplatSet = true;
- IsSplat = isSplatData();
- }
- return IsSplat;
- }
- Constant *ConstantDataVector::getSplatValue() const {
- // If they're all the same, return the 0th one as a representative.
- return isSplat() ? getElementAsConstant(0) : nullptr;
- }
- //===----------------------------------------------------------------------===//
- // handleOperandChange implementations
- /// Update this constant array to change uses of
- /// 'From' to be uses of 'To'. This must update the uniquing data structures
- /// etc.
- ///
- /// Note that we intentionally replace all uses of From with To here. Consider
- /// a large array that uses 'From' 1000 times. By handling this case all here,
- /// ConstantArray::handleOperandChange is only invoked once, and that
- /// single invocation handles all 1000 uses. Handling them one at a time would
- /// work, but would be really slow because it would have to unique each updated
- /// array instance.
- ///
- void Constant::handleOperandChange(Value *From, Value *To) {
- Value *Replacement = nullptr;
- switch (getValueID()) {
- default:
- llvm_unreachable("Not a constant!");
- #define HANDLE_CONSTANT(Name) \
- case Value::Name##Val: \
- Replacement = cast<Name>(this)->handleOperandChangeImpl(From, To); \
- break;
- #include "llvm/IR/Value.def"
- }
- // If handleOperandChangeImpl returned nullptr, then it handled
- // replacing itself and we don't want to delete or replace anything else here.
- if (!Replacement)
- return;
- // I do need to replace this with an existing value.
- assert(Replacement != this && "I didn't contain From!");
- // Everyone using this now uses the replacement.
- replaceAllUsesWith(Replacement);
- // Delete the old constant!
- destroyConstant();
- }
- Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To) {
- assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
- Constant *ToC = cast<Constant>(To);
- SmallVector<Constant*, 8> Values;
- Values.reserve(getNumOperands()); // Build replacement array.
- // Fill values with the modified operands of the constant array. Also,
- // compute whether this turns into an all-zeros array.
- unsigned NumUpdated = 0;
- // Keep track of whether all the values in the array are "ToC".
- bool AllSame = true;
- Use *OperandList = getOperandList();
- unsigned OperandNo = 0;
- for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
- Constant *Val = cast<Constant>(O->get());
- if (Val == From) {
- OperandNo = (O - OperandList);
- Val = ToC;
- ++NumUpdated;
- }
- Values.push_back(Val);
- AllSame &= Val == ToC;
- }
- if (AllSame && ToC->isNullValue())
- return ConstantAggregateZero::get(getType());
- if (AllSame && isa<UndefValue>(ToC))
- return UndefValue::get(getType());
- // Check for any other type of constant-folding.
- if (Constant *C = getImpl(getType(), Values))
- return C;
- // Update to the new value.
- return getContext().pImpl->ArrayConstants.replaceOperandsInPlace(
- Values, this, From, ToC, NumUpdated, OperandNo);
- }
- Value *ConstantStruct::handleOperandChangeImpl(Value *From, Value *To) {
- assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
- Constant *ToC = cast<Constant>(To);
- Use *OperandList = getOperandList();
- SmallVector<Constant*, 8> Values;
- Values.reserve(getNumOperands()); // Build replacement struct.
- // Fill values with the modified operands of the constant struct. Also,
- // compute whether this turns into an all-zeros struct.
- unsigned NumUpdated = 0;
- bool AllSame = true;
- unsigned OperandNo = 0;
- for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O) {
- Constant *Val = cast<Constant>(O->get());
- if (Val == From) {
- OperandNo = (O - OperandList);
- Val = ToC;
- ++NumUpdated;
- }
- Values.push_back(Val);
- AllSame &= Val == ToC;
- }
- if (AllSame && ToC->isNullValue())
- return ConstantAggregateZero::get(getType());
- if (AllSame && isa<UndefValue>(ToC))
- return UndefValue::get(getType());
- // Update to the new value.
- return getContext().pImpl->StructConstants.replaceOperandsInPlace(
- Values, this, From, ToC, NumUpdated, OperandNo);
- }
- Value *ConstantVector::handleOperandChangeImpl(Value *From, Value *To) {
- assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
- Constant *ToC = cast<Constant>(To);
- SmallVector<Constant*, 8> Values;
- Values.reserve(getNumOperands()); // Build replacement array...
- unsigned NumUpdated = 0;
- unsigned OperandNo = 0;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- Constant *Val = getOperand(i);
- if (Val == From) {
- OperandNo = i;
- ++NumUpdated;
- Val = ToC;
- }
- Values.push_back(Val);
- }
- if (Constant *C = getImpl(Values))
- return C;
- // Update to the new value.
- return getContext().pImpl->VectorConstants.replaceOperandsInPlace(
- Values, this, From, ToC, NumUpdated, OperandNo);
- }
- Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) {
- assert(isa<Constant>(ToV) && "Cannot make Constant refer to non-constant!");
- Constant *To = cast<Constant>(ToV);
- SmallVector<Constant*, 8> NewOps;
- unsigned NumUpdated = 0;
- unsigned OperandNo = 0;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- Constant *Op = getOperand(i);
- if (Op == From) {
- OperandNo = i;
- ++NumUpdated;
- Op = To;
- }
- NewOps.push_back(Op);
- }
- assert(NumUpdated && "I didn't contain From!");
- if (Constant *C = getWithOperands(NewOps, getType(), true))
- return C;
- // Update to the new value.
- return getContext().pImpl->ExprConstants.replaceOperandsInPlace(
- NewOps, this, From, To, NumUpdated, OperandNo);
- }
- Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const {
- SmallVector<Value *, 4> ValueOperands(operands());
- ArrayRef<Value*> Ops(ValueOperands);
- switch (getOpcode()) {
- case Instruction::Trunc:
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- case Instruction::PtrToInt:
- case Instruction::IntToPtr:
- case Instruction::BitCast:
- case Instruction::AddrSpaceCast:
- return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0],
- getType(), "", InsertBefore);
- case Instruction::Select:
- return SelectInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore);
- case Instruction::InsertElement:
- return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore);
- case Instruction::ExtractElement:
- return ExtractElementInst::Create(Ops[0], Ops[1], "", InsertBefore);
- case Instruction::InsertValue:
- return InsertValueInst::Create(Ops[0], Ops[1], getIndices(), "",
- InsertBefore);
- case Instruction::ExtractValue:
- return ExtractValueInst::Create(Ops[0], getIndices(), "", InsertBefore);
- case Instruction::ShuffleVector:
- return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "",
- InsertBefore);
- case Instruction::GetElementPtr: {
- const auto *GO = cast<GEPOperator>(this);
- if (GO->isInBounds())
- return GetElementPtrInst::CreateInBounds(
- GO->getSourceElementType(), Ops[0], Ops.slice(1), "", InsertBefore);
- return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0],
- Ops.slice(1), "", InsertBefore);
- }
- case Instruction::ICmp:
- case Instruction::FCmp:
- return CmpInst::Create((Instruction::OtherOps)getOpcode(),
- (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1],
- "", InsertBefore);
- case Instruction::FNeg:
- return UnaryOperator::Create((Instruction::UnaryOps)getOpcode(), Ops[0], "",
- InsertBefore);
- default:
- assert(getNumOperands() == 2 && "Must be binary operator?");
- BinaryOperator *BO = BinaryOperator::Create(
- (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], "", InsertBefore);
- if (isa<OverflowingBinaryOperator>(BO)) {
- BO->setHasNoUnsignedWrap(SubclassOptionalData &
- OverflowingBinaryOperator::NoUnsignedWrap);
- BO->setHasNoSignedWrap(SubclassOptionalData &
- OverflowingBinaryOperator::NoSignedWrap);
- }
- if (isa<PossiblyExactOperator>(BO))
- BO->setIsExact(SubclassOptionalData & PossiblyExactOperator::IsExact);
- return BO;
- }
- }
|