123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480 |
- //===-- 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 "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/ConstantFold.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/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) || isa<ConstantTargetNone>(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::containsUndefElement() const {
- return containsUndefinedElement(this, [&](const auto *C) {
- return isa<UndefValue>(C) && !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:
- case Type::BFloatTyID:
- case Type::FloatTyID:
- case Type::DoubleTyID:
- case Type::X86_FP80TyID:
- case Type::FP128TyID:
- case Type::PPC_FP128TyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat::getZero(Ty->getFltSemantics()));
- 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());
- case Type::TargetExtTyID:
- return ConstantTargetNone::get(cast<TargetExtType>(Ty));
- 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<CastConstantExpr>(C))
- delete static_cast<CastConstantExpr *>(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<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");
- }
- }
- /// 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) {
- // If C is only used by metadata, it should not be preserved but should
- // have its uses replaced.
- ReplaceableMetadataImpl::SalvageDebugInfo(*C);
- 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::getZero(Type *Ty, bool Negative) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
- APFloat NegZero = APFloat::getZero(Semantics, Negative);
- 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 *IdxTy = Type::getInt64Ty(VTy->getContext());
- // Move scalar into vector.
- Constant *PoisonV = PoisonValue::get(VTy);
- V = ConstantExpr::getInsertElement(PoisonV, V, ConstantInt::get(IdxTy, 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;
- }
- 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::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();
- // Scalable vectors can use a ConstantExpr to build a splat.
- if (isa<ConstantExpr>(this))
- return cast<ConstantInt>(this->getSplatValue())->getValue();
- // For non-ConstantExpr we use getAggregateElement as a fast path to avoid
- // calling getSplatValue in release builds.
- 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());
- }
- //---- ConstantTargetNone::get() implementation.
- //
- ConstantTargetNone *ConstantTargetNone::get(TargetExtType *Ty) {
- assert(Ty->hasProperty(TargetExtType::HasZeroInit) &&
- "Target extension type not allowed to have a zeroinitializer");
- std::unique_ptr<ConstantTargetNone> &Entry =
- Ty->getContext().pImpl->CTNConstants[Ty];
- if (!Entry)
- Entry.reset(new ConstantTargetNone(Ty));
- return Entry.get();
- }
- /// Remove the constant from the constant table.
- void ConstantTargetNone::destroyConstantImpl() {
- getContext().pImpl->CTNConstants.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::getSExtOrTrunc(Constant *C, Type *Ty) {
- assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
- "Can only sign extend/truncate integers!");
- Type *CTy = C->getType();
- if (CTy->getScalarSizeInBits() < Ty->getScalarSizeInBits())
- return getSExt(C, Ty);
- if (CTy->getScalarSizeInBits() > Ty->getScalarSizeInBits())
- return getTrunc(C, Ty);
- return C;
- }
- 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<VectorType>(C->getType())->getElementCount() ==
- cast<VectorType>(DstTy)->getElementCount() &&
- "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 *C1, Constant *C2,
- unsigned Flags, Type *OnlyIfReducedTy) {
- // Check the operands for consistency first.
- assert(Instruction::isBinaryOp(Opcode) &&
- "Invalid opcode in binary constant expression");
- assert(isSupportedBinOp(Opcode) &&
- "Binop not supported as 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);
- }
- bool ConstantExpr::isDesirableBinOp(unsigned Opcode) {
- switch (Opcode) {
- case Instruction::UDiv:
- case Instruction::SDiv:
- case Instruction::URem:
- case Instruction::SRem:
- case Instruction::FAdd:
- case Instruction::FSub:
- case Instruction::FMul:
- case Instruction::FDiv:
- case Instruction::FRem:
- return false;
- case Instruction::Add:
- case Instruction::Sub:
- case Instruction::Mul:
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- return true;
- default:
- llvm_unreachable("Argument must be binop opcode");
- }
- }
- bool ConstantExpr::isSupportedBinOp(unsigned Opcode) {
- switch (Opcode) {
- case Instruction::UDiv:
- case Instruction::SDiv:
- case Instruction::URem:
- case Instruction::SRem:
- case Instruction::FAdd:
- case Instruction::FSub:
- case Instruction::FMul:
- case Instruction::FDiv:
- case Instruction::FRem:
- return false;
- case Instruction::Add:
- case Instruction::Sub:
- case Instruction::Mul:
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- return true;
- default:
- llvm_unreachable("Argument must be binop opcode");
- }
- }
- 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,
- std::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, std::nullopt, 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, Mask);
- LLVMContextImpl *pImpl = ShufTy->getContext().pImpl;
- return pImpl->ExprConstants.getOrCreate(ShufTy, 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::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::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::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::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, bool NSZ) {
- 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
- return ConstantFP::getZero(Ty, !NSZ);
- 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, ArrayRef(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::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);
- 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;
- }
- }
|